时间轮算法在定时任务与延时消息中的应用

一、引言

1.1 背景

项目开发中,我们经常会遇到这些场景:

  • 1.小程序商城用户下单,30分钟订单未付款自动取消。
  • 2.秒杀活动开始前15分钟对设置了秒杀提醒的用户进行推送。
  • 3.用户成功秒杀到商品,5分钟未提交订单退回商品。

上述场景传统的解决方案一般是采用定时任务执行,通过设置定时任务的执行间隔,定时进行检测执行。
参考:分布式定时任务调度框架实践

1.2 缺陷

然而,定时任务的方案会存在以下不足:

  • 1.触发时间和频率不好设置。
  • 2.不能满足实时性要求高的场景。
  • 3.会导致任务对应业务处理空跑的情况,耗费资源。大部分定时任务查询不到任何数据。对宝贵的数据库资源产生不必要的消耗。

针对如上业务特点,更好的处理方式是使用延时任务技术方案,目前主流的延时任务实现方式有:

  • Kafka延时消息
  • Netty时间轮算法

二、Kafka延时消息的时间轮算法

在这里插入图片描述

tick: 时间轮里每一格;
tickDuration: 每一格的时长;
ticksPerWheel: 时间轮总共有多少格.(图中8格)
newTimeout: 定时任务分配到时间轮

时间轮(TimingWheel)是一个存储定时任务的环形队列,底层采用数组实现,数组中的每个元素可以存放一个定时任务列表(TimerTaskList)。

TimerTaskList任务列表中的每一项表示的都是定时任务项(TimerTaskEntry),其中封装了真正的定时任务TimerTask。同一时刻存在多个任务时,只要把该刻度对应的链表全部遍历一遍,执行其中的任务即可。

刻度不够怎么办?

1.增加round(轮次)属性:就像跑步一样,为每个任务加上round的计数器,当指针转过一圈时,round计数器减1,所以只需取出round=0的任务即需要触发的任务。

优点:可减少时间格过大造成的空间浪费

缺点:每次都需要遍历对应格子里面全部的任务列表,特别是当时间轮刻度粒度很小,任务列表特别长时,耗时将会大大增加。

2.采用层级时间轮:类似时钟一样,有时钟、分钟和秒钟。 层级时间轮可以进一步扩展为天轮、月轮甚至年轮。
在这里插入图片描述

比如对于分钟级时间轮来说,delayMs为1秒和delayMs为59秒的都已经过期,我们将其取出,再扔进底层的时间轮, delayMs为1秒的会被扔到秒级时间轮的下一个执行槽中,而59秒的会被扔到秒级时间轮的后59个时间槽中。

三、XXL-JOB定时任务中的时间轮

其实不仅仅是延迟消息会使用到时间轮,定时任务中也同样使用了时间轮算法进行任务的触发执行。
下面看看xxl-job任务触发和执行的总体流程图:
在这里插入图片描述
其中定时触发流程:
在这里插入图片描述

在scheduleThread将数据存入ringThread的时候,使用的就是时间轮算法的思想:
在这里插入图片描述

  • 时间轮数据结构ringData: Map<Integer, List> , key是hash计算触发时间获得的秒数(1-60),value是任务id列表
  • 入轮:扫描任务触发时 (1)本次任务处理完成,但下一次触发时间是在5秒内(2)本次任务未达到触发时间
  • 出轮:获取当前时间秒数,从时间轮内移出当前秒数前2个秒数的任务id列表, 依次进行触发任务;(避免处理耗时太长,跨过刻度,多向前校验一秒)
  • 增加时间轮的目的是:任务过多可能会延迟,为了保障触发时间尽可能和 任务设置的触发时间尽量一致,把即将要触发的任务提前放到时间轮里,每秒来触发时间轮相应节点的任务。

参考资料

https://www.cnblogs.com/wanghongsen/p/12510533.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMavs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值