1、什么是死信交换机
首先我们要知道什么是死信?
当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter):
- 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false。
- 消息是一个过期消息,超时无人消费。
- 要投递的队列消息堆积满了,最早的消息可能成为死信。
一般呢?一旦消息变成死信是会被我们丢弃的,但是有了死信交换机就不一样了。
如果这个包含死信的队列配置了dead-letter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机称为死信交换机(Dead Letter Exchange,简称DLX)。
其实呢,所谓的死信交换机就是一个普通交换机,只不过是某个队列用dead-letter-exchange这个属性绑定到一起了,当这个队列出现了死信,就会丢到我们这个死信交换机里了,就有点像垃圾桶一样的了。
如图,一个消息被消费者拒绝了,变成了死信:
因为simple.queue绑定了死信交换机 dl.direct,因此死信会投递给这个交换机:
如果这个死信交换机也绑定了一个队列,则消息最终会进入这个存放死信的队列:
另外,队列将死信投递给死信交换机时,必须知道两个信息:
- 死信交换机名称
- 死信交换机与死信队列绑定的RoutingKey
这样才能确保投递的消息能到达死信交换机,并且正确的路由到死信队列。
小结:
什么样的消息会成为死信?
- 消息被消费者reject或者返回nack。
- 消息超时未消费。
- 队列满了。
2、TTL
TTL,也就是Time-To-Live。如果一个队列中的消息TTL结束仍未消费,则会变为死信,TTL超时分为两种情况:
- 消息所在的队列设置了超时时间
- 消息本身设置了超时时间
2.1 Demo
1、准备接收超时死信的死信交换机
在consumer服务的SpringRabbitListener中,定义一个新的消费者,并且声明 死信交换机、死信队列:
/**
* @description:注解方式声明死信交换机、死信队列
* @author: jie
* @time: 20