• RabbitMQ:生产者消费者模型构建/为消息自定义属性/自定义消费者


    一.pom.xml

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.rabbitmq</groupId>
                <artifactId>amqp-client</artifactId>
                <version>3.6.5</version>
            </dependency>
        </dependencies>
    

    二.生产者

    public class Producer {
        public static void main(String[] args) throws IOException, TimeoutException {
            //创建一个连接工厂
            ConnectionFactory connectionFactory = new ConnectionFactory();
            connectionFactory.setHost("192.168.10.132");
            connectionFactory.setPort(5672);
            connectionFactory.setVirtualHost("/");
            //创建连接
            Connection connection = connectionFactory.newConnection();
            //通过连接创建一个Channel
            Channel channel = connection.createChannel();
            //通过Channel发送数据
            channel.basicPublish("","hello",null,"hello world".getBytes());
            //关闭连接
            channel.close();
            connection.close();
        }
    }
    

    这里注意channel.basicPublish方法的第一个参数(exchange)和第二个参数(routingKey),如果没有指定exchange,指定了routingKey,而routingKey与消费者类中指定的queue的name相同,会通过RabbitMQ的默认Exchange(AMQP default)进行路由。

    三.消费者

    public class Consumer {
        public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
            //创建一个连接工厂
            ConnectionFactory connectionFactory = new ConnectionFactory();
            connectionFactory.setHost("192.168.10.132");
            connectionFactory.setPort(5672);
            connectionFactory.setVirtualHost("/");
            //创建连接
            Connection connection = connectionFactory.newConnection();
            //通过连接创建一个Channel
            Channel channel = connection.createChannel();
            //创建一个队列
            String queueName = "hello";
            channel.queueDeclare(queueName,true,false,false,null);
            //创建一个消费者
            QueueingConsumer consumer = new QueueingConsumer(channel);
            //设置Channel
            channel.basicConsume(queueName,true,consumer);
            //获取消息
            while (true){
                QueueingConsumer.Delivery delivery = consumer.nextDelivery();
                String msg = new String(delivery.getBody());
                System.out.println("消费端:"+msg);
            }
    
        }
    }
    

    四.运行

    先运行消费者,再运行生产者。

    在消费者的控制台可以接收到生产者发送的消息。

    五.为消息定义属性

    1.在生产者这边:

    先设置properties:

            //自定义属性
            Map<String, Object> headers = new HashMap<>();
            headers.put("w","123");
            headers.put("w2","456");
            //为消息定义属性
            AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                    .deliveryMode(2)  //为1时,则不持久化,为2持久化消息
                    .contentEncoding("UTF-8")
                    .expiration("100000")//过期时间
                    .headers(headers)//自定义属性
                    .build();
    

    再将properties作为参数,传到basicPublish方法中

    channel.basicPublish("","hello",properties,"hello world".getBytes());
    

    2.消费者

    消费者这边,需要通过Delivery获取properties的相关属性。

            while (true){
                QueueingConsumer.Delivery delivery = consumer.nextDelivery();
                String msg = new String(delivery.getBody());
                Map<String, Object> headers = delivery.getProperties().getHeaders();
                headers.forEach((x,y)-> System.out.println(x+":"+y));
                System.out.println("消费端:"+msg);
            }
    

    打印结果:

    六.自定义消费者

    可以继承DefaultConsumer类,实现handleDelivery方法

    public class MyConsumer extends DefaultConsumer {
    
        public MyConsumer(Channel channel) {
            super(channel);
        }
    
        @Override
        public void handleDelivery(String consumerTag,
                                   Envelope envelope,
                                   AMQP.BasicProperties properties,
                                   byte[] body) throws IOException {
            System.out.println(consumerTag);
            System.out.println(envelope);
            System.out.println(properties);
            System.out.println(new String(body));
        }
    }
    

     在消费端创建消费者的时候,就可以使用自定义的消费者。

            //创建一个连接工厂
            ConnectionFactory connectionFactory = new ConnectionFactory();
            connectionFactory.setHost("192.168.10.132");
            connectionFactory.setPort(5672);
            connectionFactory.setVirtualHost("/");
            //创建连接
            Connection connection = connectionFactory.newConnection();
            //通过连接创建一个Channel
            Channel channel = connection.createChannel();
            //创建一个队列
            String queueName = "myConsumer";
            channel.queueDeclare(queueName,true,false,false,null);
            //创建一个消费者
            //QueueingConsumer consumer = new QueueingConsumer(channel);
            MyConsumer consumer = new MyConsumer(channel);
            //设置Channel
            channel.basicConsume(queueName,true,consumer);
    

     运行结果:

  • 相关阅读:
    解决 EDAS:Upload failed: The right margin is 0.535 in on page 1 问题
    解决 ImportError: No module named _internal
    静态页面如何实现 include 引入公用代码
    一个用 js 实现点阵图的编辑器演示
    从 art-template 模版维护到动态加载的思考
    Atom 备份神器 —— Sync Settings
    clicaptcha中文点击验证码开发经验总结
    通过 imagick 让 PHP 生成 PSD 文件缩略图
    让视频压制更简单
    Medoo个人修改版
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/12972301.html
Copyright © 2020-2023  润新知