死信队列的作用
使用 RabbitMQ 的时候可能会碰到以下几个问题:
- 消费者端调用了
basicNack
或者basicReject
,并且没有进行requeue
,如果没做其他措施的话,这个消息也就丢失了。 - 消息在队列的存活时间超过设置的
TTL
时间。 - 消息队列的消息数量已经超过最大队列长度。
以上几个问题都会导致消息丢失,消息丢失的代价可大可小,视自己业务情况而定,有些业务如果消息丢失无所谓的话就不用理睬,相信大部分业务都是不允许丢失的。死信队列
的出现就可以解决以上三个问题,当以上三个问题出现时,消息不会丢失,会重新放入死信队列,至于如何处理死信队列中的消息就看自己公司的业务了。
如何配置死信队列
死信队列其实本身也是普通的队列,只是在逻辑上赋予了它特殊的含义,需要绑定对应的死信交换机,与队列概念一样,也是普通的交换机,赋予了死信
的含义。那么整体流程如下:
- 创建死信交换机
-
创建死信队列
-
在死信交换机中绑定死信队列与死信交换机
-
创建业务交换机
-
创建业务队列并
关联
死信交换机与死信队列 -
在业务交换机中绑定业务队列与业务交换机
以上操作可以在 Web 上操作,亦可在项目中用代码实现。
步骤 5 中的 x-dead-letter-exchange
指定死信交换机、x-dead-letter-routing-key
指定路由到指定 Queue 的路由 key,一般配置跟 Queue 一样。
一般情况下会为每一个业务队列都配置一个相对应的死信队列,也可以多个业务队列共用一个死信队列。要注意的是业务队列和死信队列的交换机要区分开。
样例
配置如下:
spring:
rabbitmq:
host: localhost
port: 5672
username: admin
password: 123456
virtual-host: 'example'
# 生产者 ==>> Exchange 确认方式
publisher-confirm-type: correlated
# Exchange ==>> Queue
publisher-returns: true
listener:
simple:
# ACK 模式,此处选择自动 ACK
acknowledge-mode: auto
# 每次处理 100 条消息
prefetch: 100
# 决定由于监听器抛出异常而拒绝的消息是否被重新放回队列。默认值为 true,重新放回队列。这里设置为 false,如果多次重试还是异常就转发到死信队列
default-requeue-rejected: false
retry:
# 开启重试
enabled: true
# 最大重试 3 次,涵盖当前次
max-attempts: 3
# 每次重试间隔时间
initial-interval: 3000
# 最大允许重试间隔时间,用来限制 initial-interval。
max-interval: 10000
# 下一次重试的时间间隔 = 上次重试时间间隔 * multiplier
multiplier: 2
消费者端简单抛个异常:
最终都跑到死信队列了。
文章评论