RabbitMQ高级特性之死信队列和延迟队列

RabbitMQ-----死信队列

消息成为死信的三种情况

  1. 队列长度达到限制
  2. 消费者拒绝消费消息,basicNack/basicReject,并且不把消息重回队列
  3. 源队列存在消息过期限制,消息超时未消费

总结了以下两种配置

第一种配置,所有参数都放在map里面,map里的key可以看RabbirMQ中queue的Arguments参数

@Configuration
public class RabbitMQConfig {
    /**
     * 正常交换机的名称
     */
    public static final String TOPIC_EXCHANGE_BOOT = "direct_exchange-boot";
    /**
     * s信交换机的名称
     */
    public static final String DLX_EXCHANGE_BOOT = "dlx_exchange-boot";
    /**
     * 正常队列的名称
     */
    public static final String TOPIC_QUEUE1_BOOT = "direct_queue1";
    /**
     * s信队列的名称
     */
    public static final String DLX_QUEUE1_BOOT = "dlx_queue1";


    /**
     * 声明队列
     *
     * @return
     */
    @Bean("itemqueue")
    public Queue queueDeclare() {
        Map<String, Object> args = new HashMap<>(2);
        // x-dead-letter-exchange
        args.put("x-dead-letter-exchange", DLX_EXCHANGE_BOOT);
        // x-dead-letter-routing-key
        args.put("x-dead-letter-routing-key", DLX_QUEUE1_BOOT);
        //x-message-ttl
        args.put("x-message-ttl", 9000);
        //x-max-length
        args.put("x-max-length", 99);
        return QueueBuilder.durable(TOPIC_QUEUE1_BOOT).withArguments(args).build();
    }

    /**
     * 声明死信队列
     *
     * @return
     */
    @Bean("dlxqueue")
    public Queue queueDlx() {
        return QueueBuilder.durable(DLX_QUEUE1_BOOT).build();
    }

    /**
     * 声明s信交换机
     *
     * @return
     */
    @Bean("dlxexchange")
    public Exchange exchangeDlx() {
        //return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_BOOT).durable(true).build();
        return ExchangeBuilder.directExchange(DLX_EXCHANGE_BOOT).durable(true).build();
    }

    /**
     * 声明正常的交换机
     *
     * @return
     */
    @Bean("exchange")
    public Exchange exchangetopic() {
        //return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE_BOOT).durable(true).build();
        return ExchangeBuilder.directExchange(TOPIC_EXCHANGE_BOOT).durable(true).build();
    }

    /**
     * 队列绑定交换机
     *
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding queueBindExchange(@Qualifier("itemqueue") Queue queue, @Qualifier("exchange") Exchange exchange) {
        //return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();
        return BindingBuilder.bind(queue).to(exchange).with("direct_queue1").noargs();
    }


    /**
     * s信队列绑定s信交换机
     *
     * @param queue
     * @param exchange
     * @return
     */
    @Bean
    public Binding dlxQueueBindDlxExchange(@Qualifier("dlxqueue") Queue queue, @Qualifier("dlxexchange") Exchange exchange) {
        //return BindingBuilder.bind(queue).to(exchange).with("item.#").noargs();
        return BindingBuilder.bind(queue).to(exchange).with("dlx_queue1").noargs();
    }


}

第二种配置,ttl配置在生产者中

MessagePostProcessor messagePostProcessor=message -> {
                MessageProperties messageProperties = message.getMessageProperties();
                //设置编码
                messageProperties.setContentEncoding("utf-8");
                //设置过期时间10*1000毫秒
                messageProperties.setExpiration("5000");
                return message;
            };

流程
RabbitMQ高级特性之死信队列和延迟队列_第1张图片

生产者

@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitMQTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void test(){
        for (int i = 0; i < 10000; i++) {
            /*MessagePostProcessor messagePostProcessor=message -> {
                MessageProperties messageProperties = message.getMessageProperties();
//            设置编码
                messageProperties.setContentEncoding("utf-8");
//            设置过期时间10*1000毫秒
                messageProperties.setExpiration("5000");
                return message;
            };*/
            rabbitTemplate.convertAndSend(RabbitMQConfig.TOPIC_EXCHANGE_BOOT,
                    "direct_queue1", i+"");

        }
    }
}

消费者

@Component
@RabbitListener(queues = "dlx_queue1")
public class MyListen {
    @RabbitHandler
    public void getMessage(String msg, Channel channel, Message message) throws IOException {
        System.out.println("接受到的消息:"+msg);
        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false,false);
    }

}

延迟队列

延迟队列故名思议:即消息进去队列后并不是立即被消费,而是到达某一时间后,才会被消费,其实RabbitMQ中并没有延迟队列,其本质是借助ttl和死信队列结合构成与延迟队列一样的效果
延迟队列

你可能感兴趣的:(Java,RabbitMq)