分布式定时任务|青训营笔记

111 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记

分布式定时任务的实现原理

主要由三部分组成:

  • 触发器:Trigger, 解析任务,在规定时间触发要执行的任务
  • 调度器:Scheduler, 按一定规则将任务交给执行器执行任务
  • 执行器:Executor, 执行任务

Trigger

方案一:定期扫描+延时消息

截屏2022-06-11 20.23.38.png 方案二:时间轮算法

截屏2022-06-11 20.28.06.png 这也是Quartz所使用的方案,主要是通过循环数组加链表实现 循环数组的每个索引位代表不同时间段,并且每个索引位都是一个任务链表,表示在该时间需要执行的所有任务
时间轮算法的优点在于其查询和修改的复杂度都是O(1)。
在实际应用场景中,通常都是使用多级时间轮来存储任务的:

截屏2022-06-11 20.36.10.png 例如,任务2规定是在2时3分1秒时刻执行:
那么任务首先会在时轮2位置,当时轮转到2时,就会将任务转移到分轮3的位置,当分轮转到3时,又会将任务转移到秒轮,当秒轮转到1时便触发改任务的执行。

当然,当任务时间跨度大时,也可以引入天轮,月轮,年轮。

以上的描述似乎都与分布式没啥关系,分布式和单机到底有啥区别?
单机定时任务:比如一个大型项目通过五台服务器进行负载均衡,每台服务器都有业务代码和定时任务代码,并且定时任务都是通过各自的线程池定时执行的,那么同一个任务就会被执行五次,造成资源的浪费,甚至会出现数据紊乱。

容易想到的是将其余的四个服务器定时任务都删掉,只留一个来执行,这样貌似就可以解决了。但是这种单点模式发生故障的概率是很高的。

分布式定时任务调度横空出世:
任务都存放在DB中,每个触发器到触发事件时都会对数据库进行锁竞争,这样可以保证,每个任务都只被执行一次,并且,多Trigger模式出现故障的概率降低 截屏2022-06-11 20.58.46.png