RabbitMQ延迟队列的实现——TTL+死信队列DLX

大伙可以到我的RabbitMQ专栏获取更多信息

demo示例这里拿

概述

什么是延迟队列

延迟队列,即消息到达队列后不会被立即消费,只有到达指定的时间后,才会被消费

场景:

  • 下单后,30分钟为结算,自动取消该订单,被锁商品重回库存
  • 新用户注册1小时之后,发短信问候

实现方式:

  • 定时器:以某个时间间隔去轮询订单表中的下单时间并于当前时间比对,超过30分钟就取消该订单。该方式不优雅,性能消耗大,数据库压力大。
  • MQ延迟队列:当用户下单之后,订单生成,就发送一条消息到MQ延迟队列,该消息30分钟之后才能被消费,在30分钟之后,该消息被消费端接收到,开始判断该订单是否已经支付,如果没有支付,就取消该订单。优雅!

很不巧

RabbitMQ没有提供延迟队列的功能,那怎么办呢?

那就是!TTL+死信队列组合的方式,实现和延迟队列一样的效果

  1. 订单系统在用户下单后发送了一条订单信息到MQ交换机
  2. 交换机把这条消息根据routing key分发到了一个设置了30分钟过期时间队列中,但是该队列没有消费者,所以这些消息终将过期
  3. 当消息过期变成死信后,会被转发给该队列绑定的死信交换机并根据死信routing key最终被分配到了一个死信队列中
  4. 死信队列是有消费者的,这些死信消息将被这些消费者获取之后执行对应的业务逻辑

TTL+死信队列实现延迟队列效果的整个过程,其核心就是这个设置了过期时间的队列没有消费者监听,所有消息在到达过期时间后被发往了一个有消费者监听的队列

具体代码实现

具体代码请参考本专栏另外两篇文章:

RabbitMQ高级特性——消息的过期放弃TTL以及RabbitMQ消息丢弃的机制

RabbitMQ高级特性——死信队列DLX以及代码测试

写的非常的详细,另外我也上传了本专栏所有的demo到Github。