29|延时消息:如何实现高性能的定时/延时消息?
许文强
你好,我是文强。
上节课我们讲完了顺序消息和幂等机制,这节课我们来看看消息队列中的定时和延时消息是如何实现的。在消息队列中,定时和延时消息的底层技术实现是一样的,我们后面统一用延时消息来称呼。下面我们从延时消息的使用场景和定义讲起。
延时消息的场景和定义
先来看一个延时消息典型的使用场景。在网上购买商品下单的过程中,有个功能是:下单完成后 30 分钟如果没有完成支付,则这个订单就自动被取消。
如下图所示,从技术上来看,为了实现这个功能,最直观的思路是我们可以将订单数据存在 DB 的表中。然后通过定时程序每秒定时去扫描订单数据,判断如果超过 30 分钟则进行后续的处理。
这个方案的问题是,业务方维护成本较高,需要开发维护定时任务并处理扩缩容,以保证数据处理的及时性。当订单数据量很大时,就容易出现性能问题。另外可能无法实现高精度的延时。
因此理想状态是延时逻辑下沉到某个底层的引擎去实现,业务不需要感知任何延时逻辑,正常处理数据即可。在技术体系中,这个底层引擎一般由消息队列来担任。因此只要在类似这种需要定时或者延时触发某个行为的场景,都可以用到延时消息。
从技术上看,消息队列中延时消息的定义是:客户端发送设置了到期时间的消息到 Broker 后,该消息在时间到期后能被下游消费到。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
延时消息是消息队列中的重要功能之一,能够实现定时或延时触发某些行为。本文介绍了延时消息的使用场景和定义,以及延时消息的技术实现和拆解。文章详细介绍了基于轮询检测机制和基于时间轮机制的两种主流延时消息技术方案。其中,基于时间轮机制的方案能够支持任意时间精度的延时消息,并且具有较高的效率。然而,时间轮算法的工程实现挑战较大,需要考虑内存消耗、持久化和多节点同步等问题。此外,主流消息队列的延时机制实现方案也被提及,如RocketMQ基于轮询检测机制实现18个级别的延时消息,而RabbitMQ则提供了基于死信队列和集成延迟插件两种实现方案。总的来说,本文全面介绍了延时消息的技术特点和主流实现方案,对于读者快速了解延时消息具有重要参考价值。文章还提出了一个思考题,探讨了消息队列存储引擎选择的问题。文章内容丰富,涵盖了消息队列的延时消息技术及实现方案,对读者具有较高的参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解消息队列 47 讲》,新⼈⾸单¥59
《深入拆解消息队列 47 讲》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(2)
- 最新
- 精选
- 虚竹RocketMQ 5开始支持基于时间轮的任意延迟了吧
作者回复: 是的,谢谢提醒哈。这里我要调整一下内容,在5.0版本支持了。https://shimo.im/docs/gXqme9PKKpIeD7qo/read https://github.com/apache/rocketmq/wiki/RocketMQ-Improvement-Proposal
2023-10-11归属地:北京1 - shan总结 延时消息一般先将数据写入到一个临时存储,然后根据一定的机制在消息到期后让消费者可以消费到消息,主要有两个实现思路: 1. 定时任务检测:一般有独立的线程去判断数据是否到期,如果数据到期将数据取出写入到实际的Topic中,这个方案实现简单,不过在延迟消息量大的情况下到期时间可能不精准; 2. 消费时判断数据是否可见:每次消费时判断是否有到期的延时消息,虽然省去了定时线程的检测逻辑,但是每次都需要去判断是否有消息到期,可能会出现性能问题。 通常采用方案1实现延迟消息。 定时检测技术方案 1. 基于轮询检测机制的实现:由定时任务定时去检测有没有消息到期。 2. 基于时间轮机制:构建多级时间轮,再每个刻度上挂载需要处理的延时消息索引列表,依赖时间轮的推进,获取到要处理的延时消息列表,思路与方案1相似,不过有以下几个优点: (1)插入和获取的时间复杂度都是O(1); (2)可以支持任意时间精度的延时消息; (3)可以支持任何时长的延时消息; (4)每个时间刻度都可以支持任意多的元素; RocketMQ延时消息实现(基于轮询检测机制实现) RocketMQ对消息可以设置延迟级别,每个级别对应一个延迟时间,RocketMQ定义了一个延迟消息专用的主题SCHEDULE_TOPIC_XXXX,当发送延迟消息时,会将消息先存入到SCHEDULE_TOPIC_XXXX这个主题,每个延迟级别对应一个消息队列,一般会把相同延迟级别的消息投递到同一个消息队列中,每个延迟级别都有一个对应的定时任务定时检测这些延迟消息队列,有消息到期时会将消息取出,再投递到消息原本所属的Topic中,以此实现延迟消息。2023-09-16归属地:河南1
收起评论