1. 死信队列概念
死信队列(Dead Letter Exchange)死信交换器。当业务队列中的消息被拒绝或者过期或者超过队列的最大长度时,消息会被丢弃,但若是配置了死信队列,那么消息可以被重新发布到另一个交换器,这个交换器就是DLX,与DLX绑定的队列称为死信队列。
若业务队列想绑定死信队列,那么在声明业务队列时,需要指定DLX(死信Exchange)和DLK(死信RoutingKey)。
2.消息成为"死信"的前提
消息被否定确认,使用 channel.basicNack或channel.basicReject ,并且此时requeue属性被设置为false。
消息在队列的存活时间超过设置的TTL时间。
消息队列的消息数量已经超过最大队列长度。
“死信”消息会被RabbitMQ进行特殊处理,如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃。
死信队列并不是特殊的队列,只是绑定到死信交换机上的队列。死信交换机只是接受死信的普通交换机,它的类型也是[Direct、Fanout、Topic]。一般来说,会给每一个业务队列都声明一个独有的路由key,并对应配置一个死信队列进行监听(但是一个项目可共用一个死信交换机)。
3. 死信队列使用场景
在较为重要的业务场景中,确保未被消费的消息不被丢弃,一般发送消息异常可能原因主要有消息本身存在错误导致业务处理异常,参数校验异常,网络波动导致查询或调用接口异常。为了不使消息堆积,从而丢弃消息。
当发生异常时,不能每次通过日志来获取原消息,处理完问题后重新投递消息。通过配置死信队列,可以让未正确消费的消息暂存到死信队列中,后续排查清楚问题,编写相应的代码来处理死信消息(不在手动的恢复数据)。