第五部分“RabbitMQ 高级特性 - 延迟消息”

2026-04-04
6
-
- 分钟
|

延迟消息是指发送者发送消息后,指定一个时间,消费者在时间到期后才能收到并处理该消息。

它的最典型应用场景是超时未支付订单自动取消。如果不使用 MQ,通常需要用定时任务每秒轮询数据库,这会给数据库带来灾难性的并发压力,。使用延迟消息后,只需在用户下单时发送一条设定好延迟时间(如30分钟)的消息,到期后消费者检查支付状态并取消订单即可。

课程中介绍了两种实现方案以及一种极致的业务优化手段:

方案一:利用死信交换机 (DLX) 实现

这种方案属于“曲线救国”。一条消息在以下三种情况下会变成“死信”:消费者拒绝接收且不重新入队、消息过期(TTL到达)、队列已满,。

  • 实现原理:为某个没有消费者的队列设置一个“死信交换机”,。发送一条带有过期时间(如30分钟)的消息进入该队列。由于没人消费,消息在30分钟后过期变成死信,自动被路由到配置好的死信交换机,最终到达真实的消费者队列中,。

  • 缺点:配置非常繁琐,需要定义两组队列和交换机,官方并不推荐将死信交换机拿来做延迟消息使用,。

方案二:使用官方延迟消息插件 (推荐)

为了解决配置繁琐的问题,RabbitMQ 官方推出了延迟消息插件。

  • 实现原理:插件对交换机进行了改造。带有延迟时间的消息到达交换机后,会暂存在交换机内部,直到时间到期后,才会被路由转发给队列。

  • 如何使用:在代码中声明交换机时,加上 delayed=true 的属性。发送消息时,在消息头中设置延迟的毫秒数即可。

  • 缺点:交换机为了计算时间,需要在内部维护时钟并不断进行 CPU 运算。如果大量长时间(如30分钟、1小时)的延迟消息堆积,会给 CPU 带来巨大的额外压力,。因此该插件只适合延迟时间较短的场景。

方案三:针对超长延迟消息的业务极致优化

因为 90% 的用户都会在下单后的 1 分钟内完成支付,让这些订单在 MQ 中白白占用资源计时 30 分钟是非常浪费的。

  • 拆分延迟时间:将长达30分钟的延迟拆分为多个短时间的延迟(例如:10秒、10秒、15秒、15秒、30秒...等组成的集合),。

  • 循环检测:下单后发第一个10秒的延迟消息,到期检查若已支付则直接结束;若未支付,则取出下一个延迟时间再次发送延迟消息,,。这样大多数订单在头几次检查时就能完结,极大减轻了 MQ 的负担。

  • 主动查证兜底:在每次检查本地数据库发现是“未支付”时,不能轻易相信,因为可能是支付服务的“支付成功通知”还没发过来。必须主动向远端的支付服务发起查询,确保万无一失后再决定是继续发送延迟消息还是直接取消订单,。

以上就是这套 RabbitMQ 课程从基础概念、Spring AMQP 实战,到消息可靠性与延迟消息的全部核心内容梳理。您对这一部分的业务优化思路感觉如何?需要我为您展示一下这段逻辑的具体代码实现吗?

评论交流

文章目录