关于程序员:RocketMQ-消息集成多类型业务消息定时消息

37次阅读

共计 3793 个字符,预计需要花费 10 分钟才能阅读完成。

简介:本篇将持续业务音讯集成的场景,从应用场景、利用案例、性能原理以及最佳实际等角度介绍 RocketMQ 的定时音讯性能。作者:凯易、明锻 引言 Apache RocketMQ 诞生至今,历经十余年大规模业务稳定性打磨,服务了 100% 阿里团体外部业务以及阿里云数以万计的企业客户。作为金融级牢靠的业务音讯计划,RocketMQ 从创立之初就始终专一于业务集成畛域的异步通信能力构建。本篇将持续业务音讯集成的场景,从应用场景、利用案例、性能原理以及最佳实际等角度介绍 RocketMQ 的定时音讯性能。点击下方链接,查看直播解说:https://yqh.aliyun.com/live/d… 概念:什么是定时音讯 在业务音讯集成场景中,定时音讯是,生产者将一条音讯发送到音讯队列后并不冀望这条音讯马上会被消费者生产到,而是冀望到了指定的工夫,消费者才能够生产到。类似地,提早音讯其实是对于定时音讯的另外一种解释,指的是生产者冀望音讯提早肯定工夫,消费者才能够生产到。能够了解为定时到以后工夫加上肯定的延迟时间。比照一下定时音讯和一般音讯的流程。一般音讯,能够粗略的分为音讯发送,音讯存储和音讯生产三个过程。当一条音讯发送到 Topic 之后,那么这条音讯就能够马上处于期待消费者生产的状态了。

 而对于定时 / 延时音讯来说,其能够了解为在一般音讯的根底上叠加了定时投递到消费者的个性。生产者发送了一条定时音讯之后,音讯并不会马上进入用户真正的 Topic 外面,而是会被 RocketMQ 暂存到一个零碎 Topic 外面,当到了设定的工夫之后,RocketMQ 才会将这条音讯投递到真正的 Topic 外面,让消费者能够生产到。

 

 场景:为什么须要应用定时音讯 在分布式定时调度触发、工作超时解决等场景,须要实现精准、牢靠的定时事件触发。往往这类定时事件触发都会存在以下诉求:高性能吞吐:须要大量事件触发,不能有性能瓶颈。高牢靠可重试:不能失落事件触发。分布式可扩大:定时调度不能是单机零碎,须要可能平衡的调度到多个服务负载。传统的定时调度计划,往往基于数据库的工作表扫描机制来实现。大略的思路就是将须要定时触发的工作放到数据库,而后微服务利用定时触发扫描数据库的操作,实现工作捞取解决。这类计划尽管能够实现定时调度,但往往存在很多不足之处:反复扫描:在散布式微服务架构下,每个微服务节点都须要去扫描数据库,带来大量冗余的工作解决,须要做去重解决。定时距离不精确:基于定时扫描的机制无奈实现任意工夫精度的延时调度。横向扩展性差:为躲避反复扫描的问题,数据库扫表的计划里往往会依照服务节点拆分表,但每个数据表只能被单节点解决,这样会产生性能瓶颈。

 在这类定时调度类场景中,应用 RocketMQ 的定时音讯能够简化定时调度工作的开发逻辑,实现高性能、可扩大、高牢靠的定时触发能力。精度高、开发门槛低:基于音讯告诉形式不存在定时阶梯距离。能够轻松实现任意精度事件触发,无需业务去重。高性能可扩大:传统的数据库扫描形式较为简单,须要频繁调用接口扫描,容易产生性能瓶颈。音讯队列 RocketMQ 版的定时音讯具备高并发和程度扩大的能力。

 案例:应用定时音讯实现金融领取超时需要 利用定时音讯能够实现在肯定的工夫之后才进行某些操作而业务零碎不必治理定时的状态。上面介绍一个典型的案例场景:金融领取超时。当初有一个订单零碎,心愿在用户下单 30 分钟后检查用户的订单状态,如果用户还没有领取,那么就主动勾销这笔订单。

基于 RocketMQ 定时音讯,咱们能够在用户下单之后发送一条定时到 30 分钟之后的定时音讯。同时,咱们能够应用将订单 ID 设置为 MessageKey。当 30 分钟之后,订单零碎收到音讯之后,就能够通过订单 ID 查看订单的状态。如果用户超时未领取,那么就主动的将这笔订单敞开。原理:RocketMQ 定时音讯如何实现 固定距离定时音讯 如前文介绍,定时音讯的外围是如何在特定的工夫把处于零碎定时 Topic 外面的音讯转移到用户的 Topic 外面去。

 Apache RocketMQ 4.x 的版本的定时音讯是先将定时音讯放到依照 DelayLevel 放到 SCHEDULE_TOPIC_XXXX 这个零碎的不同 Queue 外面,而后为每一个 Queue 启动一个定时工作,定时的拉取音讯并将到了工夫的音讯转投到用户的 Topic 外面去。这样尽管实现简略,但也导致只能反对特定 DelayLevel 的定时音讯。当下,反对定时到任意秒级工夫的定时音讯的实现的 pr 提出到了社区,上面简略的介绍一下其根本的实现原理。工夫轮算法 在介绍具体的实现原理之前,先介绍一下经典的工夫轮算法,这是定时音讯实现的外围算法。

 如上所示,这是一个一圈定时为 7 秒的工夫轮,定时的最小精度的为秒。同时,工夫轮下面会有一个指向以后工夫的指针,其会定时的移向下一个刻度。当初咱们想定时到 1 秒当前,那么就将数据放到“1”这个刻度外面,同时如果有多个数据须要定时到同一个工夫,那么会以链表的形式增加到前面。当工夫轮转到“1”这个刻度之后,就会将其读取并从链表出队。那如果想定到超过工夫轮一圈的工夫怎么解决呢?例如咱们想定时到 14 秒,因为一圈的工夫是 7 秒,那么咱们将其放在“6”这个刻度外面。当第一次工夫轮转到“6”时,发现以后工夫小于冀望的工夫,那么疏忽这条数据。当第二次工夫轮转到“6”时,这个时候就会发现曾经到了咱们冀望的 14 秒了。任意秒级定时音讯 在 RocketMQ 中,应用 TimerWheel 对于工夫轮进行形容和存储,同时应用一个 AppendOnly 的 TimerLog 记录时间轮下面每一个刻度所对应的所有的音讯。TimerLog 记录了一条定时音讯的一些重要的元数据,用于前面定时的工夫到了之后,将音讯转移到用户的 Topic 外面去。其中几个重要的属性如下:

 对于 TimerWheel 来说,能够形象的认为是一个定长的数组,数组中的每一格代表工夫轮下面的一个“刻度”。TimerWheel 的一个“刻度”领有以下属性。

 TimerWheel 和 TimerLog 间接的关系如下图所示:

 

 TimerWheel 中的每一格代表着一个工夫刻度,同时会有一个 firstPos 指向这个刻度下所有定时音讯的首条 TimerLog 记录的地址,一个 lastPos 指向这个刻度下所有定时音讯最初一条 TimerLog 的记录的地址。并且,对于所处于同一个刻度的的音讯,其 TimerLog 会通过 prevPos 串联成一个链表。

 

 当须要新增一条记录的时候,例如当初咱们要新增一个“1-4”。那么就将新记录的 prevPos 指向以后的 lastPos,即“1-3”,而后批改 lastPos 指向“1-4”。这样就将同一个刻度下面的 TimerLog 记录全都串起来了。有了 TimerWheel 和 TimerLog 之后,咱们再来看一下一条定时音讯从发送到 RocketMQ 之后是怎么最终投递给用户的。

 

 首先,当发现用户发送的是一个定时音讯过后,RocketMQ 实际上会将这条音讯发送到一个专门用于解决定时音讯的零碎 Topic 外面去 而后在 TimerMessageStore 中会有五个 Service 进行分工合作,但整体能够分为两个阶段:入工夫轮和出工夫轮 对于入工夫轮:TimerEnqueueGetService 负责从零碎定时 Topic 外面拉取音讯放入 enqueuePutQueue 期待 TimerEnqueuePutService 的解决 TimerEnqueuePutService 负责构建 TimerLog 记录,并将其放入工夫轮的对应的刻度中  对于出工夫轮:TimerDequeueGetService 负责转动工夫轮,并取出以后工夫刻度的所有 TimerLog 记录放入 dequeueGetQueueTimerDequeueGetMessageService 负责依据 TimerLog 记录,从 CommitLog 中读取音讯 TimerDequeuePutMessageService 负责判断队列中的音讯是否曾经到期,如果曾经到期了,那么将其投入用户的 Topic 中,期待生产生产;如果还没有到期,那么从新投入零碎定时 Topic,期待从新进入工夫轮。实战:应用定时音讯 理解了 RocketMQ 秒级定时音讯的原理后,咱们看下如何应用定时音讯。首先,咱们须要创立一个“定时 / 延时音讯”类型的 Topic,能够应用控制台或者 CLi 命令创立。

 从后面能够看出,对于定时音讯来说,是在发送音讯的时候“做文章”。所以,对于生产者,绝对于发送一般音讯,咱们能够在发送的时候设置冀望的投递工夫。

 当定时的工夫到了之后,这条音讯其实就是一条投递到用户 Topic 的一般音讯而已。所以对于消费者来说,和一般音讯的生产没有区别。

 

 留神:定时音讯的实现逻辑须要先通过定时存储期待触发,定时工夫达到后才会被投递给消费者。因而,如果将大量定时音讯的定时工夫设置为同一时刻,则达到该时刻后会有大量音讯同时须要被解决,会造成零碎压力过大。所以个别倡议尽量不要设置大量雷同触发时刻的音讯。点击此处,进入官网理解更多详情~原文链接:https://click.aliyun.com/m/10… 本文为阿里云原创内容,未经容许不得转载。

正文完
 0