作者:凯易、明锻

引言

Apache RocketMQ 诞生至今,历经十余年大规模事务稳定性打磨,服务了 100% 阿里集团内部事务以及阿里云数以万计的企业客户。作为金融级牢靠的事务音讯计划,RocketMQ 从创立之初就一向专注于事务集成范畴的异步通讯才能构建。

本篇将持续事务音讯集成的场景,从运用场景、运用事例、功用原理以及最佳实践等视点介绍 RocketMQ 的守时音讯功用。

点击下方链接,查看直播讲解:

yqh.aliyun.com/live/detail…

概念:什么是守时音讯

在事务音讯集成场景中,守时音讯是,生产者将一条音讯发送到音讯队列后并不希望这条音讯立刻会被顾客消费到,而是希望到了指定的时间,顾客才能够消费到。

相似地,推迟音讯其实是关于守时音讯的别的一种解说,指的是生产者希望音讯推迟一守时间,顾客才能够消费到。能够理解为守时到当时时间加上必定的推迟时间。

比照一下守时音讯和一般音讯的流程。一般音讯,能够大略的分为音讯发送,音讯存储和音讯消费三个进程。当一条音讯发送到 Topic 之后,那么这条音讯就能够立刻处于等候顾客消费的状况了。

RocketMQ 消息集成:多类型业务消息——定时消息

而关于守时/延时音讯来说,其能够理解为在一般音讯的基础上叠加了守时投递到顾客的特性。生产者发送了一条守时音讯之后,音讯并不会立刻进入用户真实的Topic里边,而是会被 RocketMQ 暂存到一个体系 Topic 里边,当到了设定的时间之后,RocketMQ 才会将这条音讯投递到真实的 Topic 里边,让顾客能够消费到。

RocketMQ 消息集成:多类型业务消息——定时消息

场景:为什么需求运用守时音讯

在散布式守时调度触发、使命超时处理等场景,需求完成精准、牢靠的守时事情触发。往往这类守时事情触发都会存在以下诉求:

  • 高功能吞吐:需求很多事情触发,不能有功能瓶颈。
  • 高牢靠可重试:不能丢掉事情触发。
  • 散布式可扩展:守时调度不能是单机体系,需求能够均衡的调度到多个服务负载。

传统的守时调度计划,往往根据数据库的使命表扫描机制来完成。大约的思路就是将需求守时触发的使命放到数据库,然后微服务运用守时触发扫描数据库的操作,完成使命捞取处理。

这类计划尽管能够完成守时调度,但往往存在很多不足之处:

  • 重复扫描:在散布式微服务架构下,每个微服务节点都需求去扫描数据库,带来很多冗余的使命处理,需求做去重处理。
  • 守时间隔不准确:根据守时扫描的机制无法完成恣意时间精度的延时调度。
  • 横向扩展性差:为躲避重复扫描的问题,数据库扫表的计划里往往会依照服务节点拆分表,但每个数据表只能被单节点处理,这样会发生功能瓶颈。

RocketMQ 消息集成:多类型业务消息——定时消息

在这类守时调度类场景中,运用 RocketMQ 的守时音讯能够简化守时调度使命的开发逻辑,完成高功能、可扩展、高牢靠的守时触发才能。

  • 精度高、开发门槛低:根据音讯告诉方法不存在守时阶梯间隔。能够轻松完成恣意精度事情触发,无需事务去重。
  • 高功能可扩展:传统的数据库扫描方法较为复杂,需求频繁调用接口扫描,简略发生功能瓶颈。音讯队列 RocketMQ 版的守时音讯具有高并发和水平扩展的才能。

RocketMQ 消息集成:多类型业务消息——定时消息

事例:运用守时音讯完成金融支付超时需求

利用守时音讯能够完成在必定的时间之后才进行某些操作而事务体系不必办理守时的状况。下面介绍一个典型的事例场景:金融支付超时。现在有一个订单体系,希望在用户下单 30 分钟后查看用户的订单状况,假如用户还没有支付,那么就主动取消这笔订单。

RocketMQ 消息集成:多类型业务消息——定时消息

根据 RocketMQ 守时音讯,咱们能够在用户下单之后发送一条守时到 30 分钟之后的守时音讯。一起,咱们能够运用将订单 ID 设置为 MessageKey。当 30 分钟之后,订单体系收到音讯之后,就能够通过订单 ID 查看订单的状况。假如用户超时未支付,那么就主动的将这笔订单关闭。

原理:RocketMQ 守时音讯怎么完成

固定间隔守时音讯

如前文介绍,守时音讯的核心是如安在特定的时间把处于体系守时 Topic 里边的音讯转移到用户的 Topic 里边去。

RocketMQ 消息集成:多类型业务消息——定时消息

Apache RocketMQ 4.x 的版别的守时音讯是先将守时音讯放到依照 DelayLevel 放到 SCHEDULE_TOPIC_XXXX 这个体系的不同 Queue 里边,然后为每一个 Queue 启动一个守时使命,守时的拉取音讯并将到了时间的音讯转投到用户的 Topic 里边去。这样尽管完成简略,但也导致只能支撑特定 DelayLevel 的守时音讯。

当下,支撑守时到恣意秒级时间的守时音讯的完成的 pr 提出到了社区,下面简略的介绍一下其根本的完成原理。

时间轮算法

在介绍具体的完成原理之前,先介绍一下经典的时间轮算法,这是守时音讯完成的核心算法。

RocketMQ 消息集成:多类型业务消息——定时消息

如上所示,这是一个一圈守时为 7 秒的时间轮,守时的最小精度的为秒。一起,时间轮上面会有一个指向当时时间的指针,其会守时的移向下一个刻度。

现在咱们想守时到 1 秒以后,那么就将数据放到 “1” 这个刻度里边,一起假如有多个数据需求守时到同一个时间,

那么会以链表的方法添加到后边。当时间轮转到 “1” 这个刻度之后,就会将其读取并从链表出队。那假如想定到超过时间轮一圈的时间怎样处理呢?例如咱们想守时到 14 秒,由于一圈的时间是 7 秒,那么咱们将其放在“6”这个刻度里边。当第一次时间轮转到“6” 时,发现当时时间小于希望的时间,那么疏忽这条数据。当第2次时间轮转到“6”时,这个时分就会发现现已到了咱们希望的 14 秒了。

恣意秒级守时音讯

在 RocketMQ 中,运用 TimerWheel 关于时间轮进行描述和存储,一起运用一个 AppendOnly 的 TimerLog 记载时间轮上面每一个刻度所对应的一切的音讯。

TimerLog 记载了一条守时音讯的一些重要的元数据,用于后边守时的时间到了之后,将音讯转移到用户的 Topic 里边去。其中几个重要的属性如下:

RocketMQ 消息集成:多类型业务消息——定时消息

关于 TimerWheel 来说,能够抽象的认为是一个定长的数组,数组中的每一格代表时间轮上面的一个“刻度”。TimerWheel 的一个“刻度”拥有以下属性。

RocketMQ 消息集成:多类型业务消息——定时消息

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

RocketMQ 消息集成:多类型业务消息——定时消息

TimerWheel 中的每一格代表着一个时间刻度,一起会有一个 firstPos 指向这个刻度下一切守时音讯的首条 TimerLog 记载的地址,一个 lastPos 指向这个刻度下一切守时音讯最后一条 TimerLog 的记载的地址。并且,关于所处于同一个刻度的的音讯,其 TimerLog 会通过 prevPos 串联成一个链表。

RocketMQ 消息集成:多类型业务消息——定时消息

当需求新增一条记载的时分,例如现在咱们要新增一个 “1-4”。那么就将新记载的 prevPos 指向当时的 lastPos,即 “1-3”,然后修正 lastPos 指向 “1-4”。这样就将同一个刻度上面的 TimerLog 记载全都串起来了。

有了 TimerWheel 和 TimerLog 之后,咱们再来看一下一条守时音讯从发送到 RocketMQ 之后是怎样最终投递给用户的。

RocketMQ 消息集成:多类型业务消息——定时消息

首先,当发现用户发送的是一个守时音讯往后,RocketMQ 实际上会将这条音讯发送到一个专门用于处理守时音讯的体系 Topic 里边去

然后在 TimerMessageStore 中会有五个 Service 进行分工合作,但全体能够分为两个阶段:入时间轮和出时间轮

关于入时间轮:

  • TimerEnqueueGetService担任从体系守时 Topic 里边拉取音讯放入 enqueuePutQueue 等候 TimerEnqueuePutService 的处理
  • TimerEnqueuePutService 担任构建 TimerLog 记载,并将其放入时间轮的对应的刻度中

关于出时间轮:

  • TimerDequeueGetService 担任滚动时间轮,并取出当时时间刻度的一切 TimerLog 记载放入 dequeueGetQueue
  • TimerDequeueGetMessageService 担任根据 TimerLog 记载,从 CommitLog 中读取音讯
  • TimerDequeuePutMessageService 担任判别队列中的音讯是否现已到期,假如现已到期了,那么将其投入用户的 Topic 中,等候消费消费;假如还没有到期,那么重新投入体系守时 Topic,等候重新进入时间轮。

实战:运用守时音讯

了解了 RocketMQ 秒级守时音讯的原理后,咱们看下怎么运用守时音讯。首先,咱们需求创立一个 “守时/延时音讯” 类型的 Topic,能够运用控制台或许 CLi 命令创立。

RocketMQ 消息集成:多类型业务消息——定时消息

从前面能够看出,关于守时音讯来说,是在发送音讯的时分 “做文章”。所以,关于生产者,相关于发送一般音讯,咱们能够在发送的时分设置希望的投递时间。

RocketMQ 消息集成:多类型业务消息——定时消息

当守时的时间到了之后,这条音讯其实就是一条投递到用户 Topic 的一般音讯罢了。所以关于顾客来说,和一般音讯的消费没有差异。

RocketMQ 消息集成:多类型业务消息——定时消息

留意:守时音讯的完成逻辑需求先通过守时存储等候触发,守时时间抵达后才会被投递给顾客。因而,假如将很多守时音讯的守时时间设置为同一时间,则抵达该时间后会有很多音讯一起需求被处理,会形成体系压力过大。所以一般建议尽量不要设置很多相同触发时间的音讯。

点击此处,进入官网了解更多概况~