1. 什么是延迟队列
一种带有延迟功能的消息队列,Producer 将消息发送到消息队列 服务端,但并不期望这条消息立马投递,而是推迟到在当前时间点之后的某一个时间投递到 Consumer 进行消费,该消息即定时消息
2. 为什么要使用延迟队列
需求场景:
一 第三方支付平台的支付连接都是有时效性,创建订单后,需要再一定的时间内支付完成
- 微信支付、支付宝支付等
- 也可以不关闭订单,做订单二次支付的操作,但业务链路会更加复杂
- 电商业务里面还会涉及到商品库存的锁定和释放
二 消息提醒
- 备忘录提示
- 游戏开发时候清除一些buff状态
3. 业内的一些解决方案
- 定时任务高精度轮训
- 采用RocketMQ自带延迟消息功能
- RabbitMQ本身是不支持延迟队列的,怎么办?
结合死信队列的特性,就可以做到延迟消息
4. RabbitMQ死信队列
4.1 什么是rabbitmq的死信队列
没有被及时消费的消息存放的队列
4.2 什么是rabbitmq的死信交换机
Dead Letter Exchange(死信交换机,缩写:DLX)当消息成为死信后,会被重新发送到另一个交换机,这个交换机就是DLX死信交换机
4.3 消息有哪几种情况成为死信
- 消费者拒收消息**(basic.reject/ basic.nack)**,并且没有重新入队 requeue=false
- 消息在队列中未被消费,且超过队列或者消息本身的过期时间TTL(time-to-live)
- 队列的消息长度达到极限
- 消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列
5. 实战代码
5.1 死信队列配置
**
* @ClassName RabbitMQConfig
* <p>
* 发送 关单消息-》延迟exchange-》order.close.delay.queue-》死信exchange-》order.close.queue
* @Description 自定义消息队列配置
* @Author CabbageDevil
* @Version 1.0
**/
@Configuration
@Data
public class RabbitMQConfig {
/**
* 交换机
*/
private String orderEventExchange = "order.event.exchange";
/**
* 延迟队列,不能被消费者监听
*/
private String orderCloseDelayQueue = "order.close.delay.queue";
/**
* 关单队列,延迟队列消息过期后转发的队列,用于被消费者监听
*/
private String orderCloseQueue = "order.close.queue";
/**
* 进入到延迟队列的routingKey
*/
private String orderCloseDelayRoutingKey = "order.close.delay.routing.key"