RabbitMQ 死信队列

230 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

死信(Dead letter)队列是RabbitMQ中的一个高级功能,所谓死信,就是长期没有人消费的消息。

RabbitMQ中有以下几种情况会产生死信:

  • 消息被拒绝(basic.reject/baskc.nack)并且设置消息不重新返回队列 (配置spring.rabbitmq.listener.default-requeue-rejected=true 。这个属性默认是true,就是消息处理失败后,就会重新返回队列,后续重新投递。但是这里需要注意,如果队列已经满了,那就会循环不断的报错,这时候就要考虑死信了)
  • 队列达到最大长度
  • 消息TTL过期

RabbitMQ中,有一类专门处理死信的Exchange交换机和Queue队列。通过RabbitMQ的死信队列功能,可以很好的用来实现延迟队列或者消息补发之类的功能。

RabbitMQ的死信队列实现机制,是在正常队列上声明一个死信交换机dlExchange,然后这个死信交换机dlExchange可以像正常交换机Exchange一样,去绑定队列,分发消息等。其配置方式,就是在队列中增加声明几个属性来指定死信交换机。而这几个队列属性,即可以在服务器上直接配置,也可以用原生API配置,还可以用SpringBoot的方式声明Queue队列来实现,并且在SCStream框架中也支持定制。主要就是这几个属性:

#对应的死信交换机
x-dead-letter-exchange: mirror.dlExchange  
#死信交换机
x-dead-letter-routing-key: mirror.messageExchange1.messageQueue1  
#消息过期时间
routing-key x-message-ttl: 3000  
#持久化,这个是必须的。
durable: true 

这样配置完成后,在当前队列中的消息,经过3秒无人消费,就会通过指定的死信交换机mirror.dlExchange,分发到对应的死信队列中。关于如何配置这些属性,在之前声明Quorum仲裁队列和Stream队列时,都有说明。而在SCStream框架中,就可以通过以下的方式进行配置:

spring.cloud.stream.rabbit.bindings.input.destination=DlqExchange 
spring.cloud.stream.rabbit.bindings.input.group=dlQueue 
spring.cloud.stream.rabbit.bindings.output.destination=messageExchange1 
spring.cloud.stream.rabbit.bindings.output.producer.required-groups=messageQueue1 
spring.cloud.stream.rabbit.rabbit.bindings.output.producer.autoBindDlq=true 
spring.cloud.stream.rabbit.rabbit.bindings.output.producer.ttl=3000 
spring.cloud.stream.rabbit.rabbit.bindings.output.producer.deadLetterExchange=DlqExchange 
spring.cloud.stream.rabbit.rabbit.bindings.output.producer.deadLetterQueueName=DlqExchange.dlQueue

通过这样的一组配置,从output这个Binding发送的消息,经过3秒后,就会被input这个Binding对应的消费者消费到了。