一、前言
- 死信队列,英文缩写:DLX 。Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。
二、生产者代码
-
创建RabbitMQ队列配置类com.example.rabbitmq_producer.config;
@Configuration public class RabbitMQConfig { //交换机名称 public static final String ITEM_EXCHANGE = "item_exchange"; public static final String DEAD_EXCHANGE = "dead_exchange"; //队列名称 public static final String ITEM_QUEUE = "item_queue"; public static final String DEAD_QUEUE = "dead_queue"; //声明业务交换机 @Bean("itemExchange") public Exchange itemExchange(){ return ExchangeBuilder.directExchange(ITEM_EXCHANGE).durable(true).build(); } //声明死信交换机 @Bean("deadExchange") public Exchange deadExchange(){ return ExchangeBuilder.directExchange(DEAD_EXCHANGE).durable(true).build(); } //声明业务队列 @Bean("itemQueue") public Queue itemQueue(){ return QueueBuilder .durable(ITEM_QUEUE) .deadLetterExchange(DEAD_EXCHANGE) // 这里声明当前队列绑定的死信交换机 .deadLetterRoutingKey("infoDead") // 这里声明当前队列的死信路由key .build(); } //声明死信队列 @Bean("deadQueue") public Queue deadQueue(){ return QueueBuilder .durable(DEAD_QUEUE) .build(); } //绑定队列和交换机(业务) @Bean public Binding itemQueueExchange(@Qualifier("itemQueue") Queue queue, @Qualifier("itemExchange") Exchange exchange){ return BindingBuilder.bind(queue).to(exchange).with("infoRouting").noargs(); } //绑定队列和交换机(死信) @Bean public Binding deadQueueExchange(@Qualifier("deadQueue") Queue queue, @Qualifier("deadExchange") Exchange exchange){ return BindingBuilder.bind(queue).to(exchange).with("infoDead").noargs(); } }
-
编写测试类,让消息发送后超时不消费,进入死信队列;
@SpringBootTest public class RabbitMQTest { @Autowired private RabbitTemplate rabbitTemplate; @Test public void test(){ MessageProperties messageProperties = new MessageProperties(); // 设置过期时间,单位:毫秒 messageProperties.setExpiration("5000"); byte[] msgBytes = "rabbitmq ttl message ...".getBytes(); Message message = new Message(msgBytes, messageProperties); //发送消息 rabbitTemplate.convertAndSend(RabbitMQConfig.ITEM_EXCHANGE,"infoRouting",message); System.out.println("发送消息成功"); } }
三、消费者代码
-
编写消息监听器com.example.rabbitmq_consumer.listener;
@Component public class MyListener { @RabbitListener(queues = "dead_queue") public void printMsg(String msg) throws IOException { System.out.println("成功获取死信队列消息:" + msg); } }
四、总结
-
死信交换机和死信队列和普通的没有区别
-
当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列
-
消息成为死信的三种情况:
- 队列消息长度到达限制;
- 消费者拒接消费消息,并且不重回队列;
- 原队列存在消息过期设置,消息到达超时时间未被消费;