Rabbitmq-使用篇

一、RabbitMQ使用-maven

  • RabbitMQ工作模式

RabbitMQ共有六种工作模式:简单模式(Simple)、工作队列模式(Work Queue)、发布订阅模式(Publish/Subscribe)、路由模式(Routing)、通配符模式(Topics)、远程调用模式(RPC,不常用,课程不对此模式进行讲解)

导入依赖

    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.14.0</version>
        </dependency>
    </dependencies>

创建连接

        // 1.创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.xx.xx");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("itxiong");
        connectionFactory.setPassword("itxiong");
        connectionFactory.setVirtualHost("/");
        // 2.创建连接
        Connection conn = connectionFactory.newConnection();
        // 3.建立信道
        Channel channel = conn.createChannel();

使用模式


①、简单模式

  • Simple模式特点:
    • 一个生产者对应一个消费者 \textcolor{red}{一个生产者对应一个消费者} 一个生产者对应一个消费者,通过队列进行消息传递。
    • 该模式使用direct交换机,direct交换机是RabbitMQ默认交换机。
生产者
队列
消费者
  • 生产者
        // 4.创建队列,如果队列已存在,则使用该队列
        /**
         * 参数1:队列名
         * 参数2:是否持久化,true表示MQ重启后队列还在。
         * 参数3:是否私有化,false表示所有消费者都可以访问,true表示只有第一次拥有它的消费者才能访问
         * 参数4:是否自动删除,true表示不再使用队列时自动删除队列
         * 参数5:其他额外参数
         */
        channel.queueDeclare("simple_queue", false, false, false, null);
        // 5.发送消息
        String message = "hello!rabbitmq!";
        /**
         * 参数1:交换机名,""表示默认交换机
         * 参数2:路由键,简单模式就是队列名
         * 参数3:其他额外参数
         * 参数4:要传递的消息字节数组
         */
        channel.basicPublish("", "simple_queue", null, message.getBytes());
        // 6.关闭信道和连接
        channel.close();
        connection.close();
        System.out.println("===发送成功===");
  • 消费者
        // 4.监听队列
        /**
         * 参数1:监听的队列名
         * 参数2:是否自动签收,如果设置为false,则需要手动确认消息已收到,否则MQ会一直发送消息
         * 参数3:Consumer的实现类,重写该类方法表示接受到消息后如何消费
         */
        channel.basicConsume("simple_queue", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "UTF-8");
                System.out.println("接受消息,消息为:" + message);
            }
        });

②、工作队列模式

与简单模式相比,工作队列模式(Work Queue)多了一些消费者,该模式也使用direct交换机,应用于处理消息较多的情况。Work Queue模式特点如下:

  • 一个队列对应多个消费者 \textcolor{red}{一个队列对应多个消费者} 一个队列对应多个消费者
  • 一条消息只会被一个消费者消费。
  • 消息队列默认采用轮询的方式将消息平均发送给消费者。
生产者
队列
消费者1
消费者2
  • 生产者
        // 4.创建队列,持久化队列
        channel.queueDeclare("work_queue", true, false, false, null);
        // 5.发送大量消息,参数3表示该消息为持久化消息,即除了保存到内存还会保存到磁盘中
        for (int i = 1; i <= 100; i++) {
    
    
            channel.basicPublish("", "work_queue", MessageProperties.PERSISTENT_TEXT_PLAIN, ("你好,这是今天的第" + i + "条消息").getBytes());
        }
        // 6.关闭资源
        channel.close();
        connection.close();
  • 消费者
        // 4.监听队列,处理消息
        channel.basicConsume("work_queue", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "UTF-8");
                System.out.println("消费者1消费消息,消息为:" + message);
            }
        });

③、发布订阅模式

Publish/Subscribe模式特点:

  1. 生产者将消息发送给交换机,交换机将消息转发到绑定此交换机的每个队列中。
  2. 工作队列模式的交换机只能将消息发送给一个队列,发布订阅模式的交换机能将消息发送给多个队列。
  3. 发布订阅模式使用fanout交换机。
生产者
队列1
队列2
消费者1
消费者2
  • 生产者
        // 4.创建交换机
        /**
         * 参数1:交换机名
         * 参数2:交换机类型
         * 参数3:交换机持久化
         */
        channel.exchangeDeclare("exchange_fanout", BuiltinExchangeType.FANOUT, true);
        // 5.创建队列
        channel.queueDeclare("SEND_MAIL", true, false, false, null);
        channel.queueDeclare("SEND_MESSAGE", true, false, false, null);
        channel.queueDeclare("SEND_STATION", true, false, false, null);
        // 6.交换机绑定队列
        /**
         * 参数1:队列名
         * 参数2:交换机名
         * 参数3:路由关键字,发布订阅模式写""即可
         */
        channel.queueBind("SEND_MAIL", "exchange_fanout", "");
        channel.queueBind("SEND_MESSAGE", "exchange_fanout", "");
        channel.queueBind("SEND_STATION", "exchange_fanout", "");
        // 7.发送消息
        for (int i = 1; i <= 10; i++) {
    
    
            channel.basicPublish("exchange_fanout", "", null, ("你好,尊敬的用户,秒杀商品开抢了!" + i).getBytes(StandardCharsets.UTF_8));
        }
        // 8.关闭资源
        channel.close();
        connection.close();
  • 消费者

站内信消费者

        // 4.监听队列
        channel.basicConsume("SEND_STATION", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送站内信:"+message);
            }
        });

邮件消费者

        // 4.监听队列
        channel.basicConsume("SEND_MAIL", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送邮件:" + message);
            }
        });

短信消费者

        // 4.监听队列
        channel.basicConsume("SEND_MESSAGE", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送短信:" + message);
            }
        });

④、路由模式

Routing模式特点:

  • 每个队列绑定路由关键字RoutingKey
  • 生产者将带有RoutingKey的消息发送给交换机,交换机根据RoutingKey转发到指定队列。路由模式使用direct交换机。
orange
black
green
生产者
交换机
队列1
队列2
消费者1
消费者2
  • 生产者
        // 4.创建交换机
        channel.exchangeDeclare("exchange_routing", BuiltinExchangeType.DIRECT, true);
        // 5.创建队列
        channel.queueDeclare("SEND_MAIL2", true, false, false, null);
        channel.queueDeclare("SEND_MESSAGE2", true, false, false, null);
        channel.queueDeclare("SEND_STATION2", true, false, false, null);
        // 6.交换机绑定队列
        channel.queueBind("SEND_MAIL2", "exchange_routing", "import");
        channel.queueBind("SEND_MESSAGE2", "exchange_routing", "import");
        channel.queueBind("SEND_STATION2", "exchange_routing", "import");
        channel.queueBind("SEND_STATION2", "exchange_routing", " normal");
        // 7.发送消息
        channel.basicPublish("exchange_routing", "import", null, "双十一大促活动".getBytes());
        channel.basicPublish("exchange_routing", "normal", null, "小心促销活动".getBytes());
        // 8.关闭资源
        channel.close();
        connection.close();
  • 消费者

站内信消费者

        // 4.监听队列
        channel.basicConsume("SEND_STATION2", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送站内信:" + message);
            }
        });

邮件消费者

        // 4.监听队列
        channel.basicConsume("SEND_MAIL2", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void
            handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送邮件:" + message);
            }
        });

短信消费者

        // 4.监听队列
        channel.basicConsume("SEND_MESSAGE2", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void
            handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送短信:" + message);
            }
        });

⑤、通配符模式

Topics模式规则:

  • 消息设置RoutingKey时,RoutingKey由多个单词构成,中间以 . 分割。
  • 队列设置RoutingKey时, # 可以匹配任意多个单词, * 可以匹配任意一个单词。
*.orange.*
*.*.rabbit
lazy.#
生产者
交换机
队列1
队列2
消费者1
消费者2
  • 生产者
        // 4.创建交换机
        channel.exchangeDeclare("exchange_topic", BuiltinExchangeType.TOPIC, true);
        // 5.创建队列
        channel.queueDeclare("SEND_MAIL3", true, false, false, null);
        channel.queueDeclare("SEND_MESSAGE3", true, false, false, null);
        channel.queueDeclare("SEND_STATION3", true, false, false, null);
        // 6.交换机绑定队列
        channel.queueBind("SEND_MAIL3", "exchange_topic","#.mail.#");
        channel.queueBind("SEND_MESSAGE3", "exchange_topic","#.message.#");
        channel.queueBind("SEND_STATION3", "exchange_topic","#.station.#");
        // 7.发送消息
        channel.basicPublish("exchange_topic", "mail.message.station", null, "双十一大促活动" .getBytes());
        channel.basicPublish("exchange_topic", "station",null, "小型促销活动" .getBytes());
        // 8.关闭资源
        channel.close();
        connection.close();
  • 消费者

通配符消费者

        // 4.监听队列
        channel.basicConsume("SEND_STATION3", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送站内信:"+message);
            }
        });

邮件消费者

        // 4.监听队列
        channel.basicConsume("SEND_MAIL3", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void
            handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送邮件:" + message);
            }
        });

短信消费者

        // 4.监听队列
        channel.basicConsume("SEND_MESSAGE3", true, new DefaultConsumer(channel) {
    
    
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
    
    
                String message = new String(body, "utf-8");
                System.out.println("发送短信:"+message);
            }
        });

二、RabbitMQ使用-SpringBoot

version1.0

导入依赖

    <dependencies>
        <!-- RabbitMQ 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

配置文件

①、入门配置

# rabbitmq 配置
spring:
  rabbitmq:
   host: 192.168.xx.xx
   port: 5672
   username: guest
   password: guest
   virtual-host: /
# 日志格式
logging:
  pattern:
    console: '[%yellow(%date{yyyy-MM-dd HH:mm:ss.SSS}) %highlight(%-5level)] [%cyan(%X{traceid}) %magenta(%-15thread)] [%green(%-50logger){50}] : %.4000m%n'

②、消息的可靠性投递

生产者
# rabbitmq 配置
spring:
  rabbitmq:
    host: 192.168.xx.xx
    port: 5672
    username: guest 
    password: guest
    virtual-host: /
    # 开启确认模式
    publisher-confirm-type: correlated
    # 开启回退模式
    publisher-returns: true
# 日志格式
logging:
  pattern:
    console: '[%yellow(%date{yyyy-MM-dd HH:mm:ss.SSS}) %highlight(%-5level)] [%cyan(%X{traceid}) %magenta(%-15thread)] [%green(%-50logger){50}] : %.4000m%n'
    
消费者
# rabbitmq 配置
spring:
  rabbitmq:
    host: 192.168.xx.xx
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    # 开启手动签收:manual(手动),none(自动)
    listener:
     simple:
      acknowledge-mode: manual
      # (消费端限流)消费端最多拉取5条消息消费,签收后不满5条才会继续拉取消息。
      prefetch: 5 # (设置为1,不公平分发)这样谁处理的快谁拉取下一条消息,实现了不公平分发
# 日志格式
logging:
  pattern:
    console: '[%yellow(%date{yyyy-MM-dd HH:mm:ss.SSS}) %highlight(%-5level)] [%cyan(%X{traceid}) %magenta(%-15thread)] [%green(%-50logger){50}] : %.4000m%n'

使用RabbitMQ

生产者

配置队列交换机
①、一般配置

SpringBoot整合RabbitMQ时,需要在配置类创建队列和交换机

  1. 创建交换机
  2. 创建队列
  3. 交换机绑定队列
@Configuration
public class RabbitConfig3 {
    
    
    private final String EXCHANGE_NAME = "boot_topic_exchange";
    private final String DEAD_EXCHANGE = "dead_exchange";
//    private final String QUEUE_NAME = "boot_queue";
    private final String QUEUE_NAME = "my_queue";

    /**
     * 创建交换机
     */
    @Bean("bootExchange")
    public Exchange getExchange() {
    
    
        return ExchangeBuilder
                .topicExchange(EXCHANGE_NAME) // 交换机类型
                .durable(true) // 是否持久化
                .build();
    }

    /**
     * 1. 创建队列
     *      方式一: new Queue(QUEUE_NAME);
     *      方式二: 链式编程 QueueBuilder。durable(QUEUE_NAME).build();
     * 2. 设置消息存活时间(ms)
     *      QueueBuilder.ttl(10000) // 设置队列中每条消息存活的时间
     * 3. 设置队列的优先级(1~255)
     *      QueueBuilder.maxPriority(10) //设置队列的最大优先级,最大可以设置到255,官网推荐不要超过10,,如果设置太高比较浪费资源
     * 4. 创建死信交换机(配置两个队列)
     *      QueueBuilder.deadLetterExchange(DEAD_EXCHANGE).deadLetterRoutingKey("dead_routing")  // 绑定死信交换机名,路由关键字
     */
    @Bean("bootQueue")
    public Queue getMessageQueue() {
    
    
//         // 队列名
        return QueueBuilder
                .durable(QUEUE_NAME)  //队列持久化
                .deadLetterExchange(DEAD_EXCHANGE) // 绑定死信 交换机
                .deadLetterRoutingKey("dead_routing") // 死信 队列路由关键字
                .ttl(10000) // 设置队列中每条消息存活的时间
                .maxPriority(10) //设置队列的最大优先级,最大可以设置到255,官网推荐不要超过10,,如果设置太高比较浪费资源
                .build();
    }

    /**
     * 交换机绑定队列
     * with: 绑定的路由
     *      入门配置:.with("my_routing")
     *      路由模式:.with("#.message.#")
     */
    @Bean
    public Binding bindMessageQueue(@Qualifier("bootExchange") Exchange exchange, @Qualifier("bootQueue") Queue queue) {
    
    
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("my_routing")
                //.with("#.message.#")
                .noargs();
    }
}
②、死信交换机配置
  • 消息成为死信的情况:
  1. 队列消息长度到达限制。
  2. 消费者拒签消息,并且不把消息重新放入原队列。
  3. 消息到达存活时间未被消费。
  1. 创建死信交换机&队列,普通交换机&队列
  2. 普通交换机&队列设置长度、优先级
  3. 普通交换机&队列绑定死信交换机&队列
@Configuration
public class RabbitConfig4 {
    
    
    private final String DEAD_EXCHANGE = "dead_exchange";
    private final String DEAD_QUEUE = "dead_queue";
    private final String NORMAL_EXCHANGE = "normal_exchange";
    private final String NORMAL_QUEUE = "normal_queue";

    // 死信交换机
    @Bean(DEAD_EXCHANGE)
    public Exchange deadExchange() {
    
    
        return ExchangeBuilder
                .topicExchange(DEAD_EXCHANGE)
                .durable(true)
                .build();
    }

    // 死信队列
    @Bean(DEAD_QUEUE)
    public Queue deadQueue() {
    
    
        return QueueBuilder
                .durable(DEAD_QUEUE)
                .build();
    }

    // 死信交换机绑定死信队列
    @Bean
    public Binding bindDeadQueue(@Qualifier(DEAD_EXCHANGE) Exchange exchange, @Qualifier(DEAD_QUEUE) Queue queue) {
    
    
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("dead_routing")
                .noargs();
    }

    // 普通交换机
    @Bean(NORMAL_EXCHANGE)
    public Exchange normalExchange() {
    
    
        return ExchangeBuilder
                .topicExchange(NORMAL_EXCHANGE)
                .durable(true)
                .build();
    }

    // 普通队列
    @Bean(NORMAL_QUEUE)
    public Queue normalQueue() {
    
    
        return QueueBuilder
                .durable(NORMAL_QUEUE)
                .deadLetterExchange(DEAD_EXCHANGE) // 绑定死信 交换机
                .deadLetterRoutingKey("dead_routing") // 死信队列路由关键字
                .ttl(10000) // 消息存活10s
                .maxLength(10) // 队列最大长度为10
                .build();
    }

    // 普通交换机绑定普通队列
    @Bean
    public Binding
    bindNormalQueue(@Qualifier(NORMAL_EXCHANGE) Exchange exchange, @Qualifier(NORMAL_QUEUE) Queue queue) {
    
    
        return BindingBuilder
                .bind(queue)
                .to(exchange)
                .with("my_routing")
                .noargs();
    }
}
③、延迟队列
@Configuration
public class RabbitConfig5 {
    
    
    public final String DELAYED_EXCHANGE = "delayed_exchange";
    public final String DELAYED_QUEUE = "delayed_queue";

    /**
     * 1.延迟交换机
     */
    @Bean(DELAYED_EXCHANGE)
    public Exchange delayedExchange() {
    
    
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "topic"); // topic类型的延迟交换机
        /**
         * 参数一:交换机的名字
         * 参数二:交换机的类型
         * 参数三:是否是持久化
         * 参数四:是否自动删除
         * 参数五:配置
         */
        return new CustomExchange(DELAYED_EXCHANGE, "x-delayed-message", true, false, args);
    }

    /**
     * 2.延迟队列
     */
    @Bean(DELAYED_QUEUE)
    public Queue delayedQueue() {
    
    
        return QueueBuilder
                .durable(DELAYED_QUEUE)
                .build();
    }

    /**
     * 3.绑定
     */
    @Bean
    public Binding
    bindingDelayedQueue(@Qualifier(DELAYED_QUEUE) Queue queue, @Qualifier(DELAYED_EXCHANGE) Exchange exchange) {
    
    
        return BindingBuilder.bind(queue).to(exchange)
                .with("order_routing")
                .noargs();
    }
}
发送消息
①、入门配置

RabbitTemplate:发送消息对象

@SpringBootTest
public class TestProducer {
    
    
    // 注入RabbitTemplate工具类
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSendMessage() {
    
    
        /**
         * 发送消息
         * 参数1:交换机
         * 参数2:路由key
         * 参数3:要发送的消息
         */
        rabbitTemplate.convertAndSend("boot_topic_exchange","message","双十一开始了!");
    }
}
②、可靠性投递

RabbitTemplate

  1. setConfirmCallback:设置确认模式
  2. setReturnsCallback:设置回退模式
@SpringBootTest
public class TestProducer {
    
    
    // 注入RabbitTemplate工具类
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 确认模式
     */
    @Test
    public void testConfirm() {
    
    
        // 定义确认模式的回调方法,消息向交换机发送后会调用confirm方法
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
    
    
            /**
             * 被调用的回调方法
             * @param correlationData 相关配置信息
             * @param ack 交换机是否成功收到了消息
             * @param cause 失败原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
    
    
                if (ack) {
    
    
                    System.out.println("confirm接受成功!");
                } else {
    
    
                    System.out.println("confirm接受失败,原因为:" + cause);
                    // 做一些处理。
                }
            }
        });
        /**
         *  发送消息
         * 参数1:交换机
         * 参数2:路由key
         * 参数3:要发送的消息
         */
        rabbitTemplate.convertAndSend("boot_topic_exchange", "my_routing", "send message...");
    }
    
     /**
     * 回退模式
     */
    @Test
    public void testReturn() {
    
    
        // 定义退回模式的回调方法。交换机发送到队列失败后才会执行returnedMessage方法
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
    
    
            /**
             * @param returned 失败后将失败信息封装到参数中
             */
            @Override
            public void returnedMessage(ReturnedMessage returned) {
    
    
                System.out.println("消息对象:" + returned.getMessage());
                System.out.println("错误码:" + returned.getReplyCode());
                System.out.println("错误信息:" + returned.getReplyText());
                System.out.println("交换机:" + returned.getExchange());
                System.out.println("路由键:" + returned.getRoutingKey());
                // 处理消息...
            }
        });
        rabbitTemplate.convertAndSend("my_topic_exchange", "my_routing", "send message...");
    }
}
③、消息存活时间

设置单条消息存活时间(ms):messageProperties.setExpiration(“10000”);

@SpringBootTest
public class TestProducer {
    
    
    // 注入RabbitTemplate工具类
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 设置单条消息的生存时间
     */
    @Test
    public void testMessageTtl() {
    
    
        //设置消息属性
        MessageProperties messageProperties = new MessageProperties();
        //设置存活时间
        messageProperties.setExpiration("10000");
        // 创建消息对象
        Message message = new Message("sendmessage...".getBytes(StandardCharsets.UTF_8), messageProperties);
        // 发送消息
        rabbitTemplate.convertAndSend("boot_topic_exchange", "my_queue", message);
    }
}
④、设置消息优先级

设置消息优先级:messageProperties.setPriority(9);

@SpringBootTest
public class TestProducer {
    
    
    // 注入RabbitTemplate工具类
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 设置消息的优先级
     */
    @Test
    public void testPriority() {
    
    
        for (int i = 0; i < 10; i++) {
    
    
            if (i == 5) {
    
    
                // i为5时消息的优先级较高
                MessageProperties messageProperties = new MessageProperties();
                messageProperties.setPriority(9);
                Message message = new Message(("send message..." + i).getBytes(StandardCharsets.UTF_8), messageProperties);
                rabbitTemplate.convertAndSend("priority_exchange", "my_routing", message);
            } else {
    
    
                rabbitTemplate.convertAndSend("priority_exchange", "my_routing", " send message..." + i);
            }
        }
    }
}

消费者

接受消息

①、入门使用
  1. @RabbitListener:监听队列名
  2. 方法参数
@Component
public class Consumer {
    
    
    // 监听队列
    @RabbitListener(queues = "boot_queue")
    public void listen_message(String mes) {
    
    
        System.out.println("发送短信:" + mes);
    }
}
②、消息的可靠性投递
@Component
public class Consumer {
    
    

    /**
     * 消费者消息确认
     */
    @RabbitListener(queues = "my_queue")
    public void listenMessage(Message message, Channel channel) throws IOException, InterruptedException {
    
    
        // 消息投递序号,消息每次投递该值都会+1
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
    
    
            //int i = 1 / 0; //模拟处理消息出现bug
            System.out.println("成功接受到消息:" + new String(message.getBody(),"UTF-8"));
            /**
             * 签收消息
             * 参数1:消息投递序号
             * 参数2:是否一次可以签收多条消息
             */
            channel.basicAck(deliveryTag, true);
        } catch (Exception e) {
    
    
            System.out.println("消息消费失败!");
            Thread.sleep(2000);
            /**
             * 拒签消息
             * 参数1:消息投递序号
             * 参数2:是否一次可以拒签多条消息
             * 参数3:拒签后消息是否重回队列
             */
            channel.basicNack(deliveryTag, true, true);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_56571862/article/details/128740589