相关知识
什么是延迟队列
队列中的消息在等待指定时间后,消费者才能够进行消费。
应用场景
商城系统,下单后半个小时未付款,自动取消订单
实现方式
RabbitMQ 本身没有直接支持延迟队列功能,但是通过控制消息的生存时间及死信队列,可以模拟出延迟队列的效果。
RabbitMQ 控制消息的生存时间有两种方法:
- 设置队列属性(x-message-ttl),队列中所有消息都有相同的过期时间
- 设置消息属性(expiration),拥有单独的过期时间
关于死信队列可以参考 https://gitee.com/gongm_24/spring-boot-tutorial/tree/master/chapter18
目标
整合 Spring boot 提供的 spring-boot-starter-amqp,实现延迟队列
操作步骤
添加依赖
添加后的整体依赖如下
定义队列
定义一个测试队列 TestDeadQueue,并为该队列配置死信队列,配置的方法就是在声明队列的时候,添加参数 x-dead-letter-exchange 及 x-dead-letter-routing-key,其实就是在消费失败时,将消息使用该 exchange 及 routing 发送至指定队列
消息接收方
测试代码
消息重试
使用延时消息我们还可以实现一种业务场景:延迟的消息重试。
有些时候我们可能以为一些原因,导致消息在某一时段处理的失败,但是假如马上进行重试可能会再次失败,我们希望稍后对其进行处理且设置一个可控的重试次数。此时我们可以在延迟消息中进行修改来实现消息重试。
重试的流程
根据上面的设计,我们需要三个消息队列workQueue
业务队列、retryQueue
重试队列、failedQueue
失败队列。
配置exchange和queue
workQueue
业务处理所订阅的内容,普通队列
retryQueue
延时队列,其配置了死信相关参数,其死信队列为workqueue
failedQueue
重试次数超过上限后的消息处理队列,没有额外处理
配置消息发送者
配置消息监听者
在对work_queue的消息订阅中,模拟了业务逻辑,进行重试或者转发至失败队列
失败队列的订阅处理中一般会进行数据的持久化,以方便后续人工介入进行业务处理