SpringBoot2.0实战(12)整合RabbitMQ之死信队列

相关知识

什么是死信队列

“死信”是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况:

  • 消息被否定确认,使用 channel.basicNack 或 channel.basicReject ,并且此时requeue 属性被设置为false。
  • 消息在队列的存活时间超过设置的TTL时间。
  • 消息队列的消息数量已经超过最大队列长度。

那么该消息将成为“死信”,“死信”消息会被RabbitMQ进行特殊处理。如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃。

应用场景

当一个队列中的消息必须要被正确消费,但是却无法被正确消费,有很多情况可能导致出现这个问题,可能是消息本身的数据导致业务无法通过校验,也可能是相关服务宕机导致,甚至可能只是网络波动导致。此时该消息不能确认,也不能丢弃,更不能一直 requeue,那将变成一个死循环,这种消息不能一直呆在当前业务队列阻塞其它消息,但又需要处理,把它们导航至死信队列就是一种解决办法,通过订阅死信队列可以对此类消息进行例外处理,例如通知相关人员检查数据进行人工处理。

目标

整合 Spring boot 提供的 spring-boot-starter-amqp,实现消息消费失败转死信队列

操作步骤

添加依赖

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

 

编码(发送方)

配置

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

 

定义队列

定义一个测试队列 TestDeadQueue,并为该队列配置死信队列,配置的方法就是在声明队列的时候,添加参数 x-dead-letter-exchange 及 x-dead-letter-routing-key,其实就是在消费失败时,将消息使用该 exchange 及 routing 发送至指定队列

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

 

测试发送

 

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

编码(消费方)

配置

配置消费消息使用手动确认模式

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

 

定义队列

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

 

消费

定义队列 TestDirectQueue 的消费方法,在方法中调用了 basicReject 方法,用于告诉 RabbitMQ 消费失败,调用 basicReject 方法时 requeue 参数必须为 false,不然就会把消息重新加入当前队列,由于队列 TestDirectQueue 配置了死信队列,于是 RabbitMQ 在接收到消费失败的 ACK 后,将当前消息根据配置的 exchange 及 routing 进行再次发送,并从当前队列中删除,消息最终被发送至队列 DeadQueue。

SpringBoot2.0实战(12)整合RabbitMQ之死信队列

 

源码地址

本章源码 : https://github.com/caiyuanzi-song/boot.git

结束语

死信队列其实并没有什么神秘的地方,不过是绑定在死信交换机上的普通队列,而死信交换机也只是一个普通的交换机,不过是用来专门处理死信的交换机。

总结一下死信消息的生命周期:

SpringBoot2.0实战(12)整合RabbitMQ之死信队列