RabbitMQ延迟队列的实现——TTL+死信队列DLX
大伙可以到我的RabbitMQ专栏获取更多信息
demo示例这里拿
概述
什么是延迟队列
延迟队列,即消息到达队列后不会被立即消费,只有到达指定的时间后,才会被消费
场景:
- 下单后,30分钟为结算,自动取消该订单,被锁商品重回库存
- 新用户注册1小时之后,发短信问候
实现方式:
- 定时器:以某个时间间隔去轮询订单表中的下单时间并于当前时间比对,超过30分钟就取消该订单。该方式不优雅,性能消耗大,数据库压力大。
- MQ延迟队列:当用户下单之后,订单生成,就发送一条消息到MQ延迟队列,该消息30分钟之后才能被消费,在30分钟之后,该消息被消费端接收到,开始判断该订单是否已经支付,如果没有支付,就取消该订单。优雅!
很不巧
RabbitMQ没有提供延迟队列的功能,那怎么办呢?
那就是!TTL+死信队列组合的方式,实现和延迟队列一样的效果。
- 订单系统在用户下单后发送了一条订单信息到MQ交换机
- 交换机把这条消息根据routing key分发到了一个设置了30分钟过期时间队列中,但是该队列没有消费者,所以这些消息终将过期
- 当消息过期变成死信后,会被转发给该队列绑定的死信交换机并根据死信routing key最终被分配到了一个死信队列中
- 死信队列是有消费者的,这些死信消息将被这些消费者获取之后执行对应的业务逻辑
TTL+死信队列实现延迟队列效果的整个过程,其核心就是这个设置了过期时间的队列没有消费者监听,所有消息在到达过期时间后被发往了一个有消费者监听的队列。
具体代码实现
具体代码请参考本专栏另外两篇文章:
RabbitMQ高级特性——消息的过期放弃TTL以及RabbitMQ消息丢弃的机制
写的非常的详细,另外我也上传了本专栏所有的demo到Github。