这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
实现原理
整体架构
- 核心架构
触发:在什么时间点触发
调度:当被触发后,如何在成百上千台机器上进行调度
执行:单台机器如何执行好分配的任务,如何进行状态恢复
- 数据流
任务基础信息:谁建的,用于干什么。。。
触发规则:周期执行还是延时执行。。。
任务代码:被调度时执行的代码
控制台:将任务信息存储到DB里面
触发器:判断到时候进行触发
调度器:进行任务协调
- 功能架构
控制台Admin
任务实例失败会重试,每次重试都会有一个任务结果
任务元数据
任务元数据:是用户对任务基础信息定义,包括任务类型调度时机、执行行为、执行方式。
任务实例
任务实例(Joblnstance)是一个确定的Job的一次运行实例
触发器Trigger
方案一:定时扫描+延时消息
扫描器每10s扫描DB看看最近10分钟要执行的任务,将其送入processor,processor会对DB中状态进行修改,并将这些任务放入延时队列中等待执行
方案二:Quartz方案——时间轮
时间轮是一种高效利用线程资源进行批量化调度的一种调度模型。时间轮是一个存储环形队列,底层采用数组实现,数组中的每个元素可以存放一个定时任务列表。
- 方案1
-
方案2
任务很多时,数组长度会无限大,空间复杂度O(n)
-
方案3:使用时间轮存储任务
- 时钟每一格代表该时间点要执行的任务列表
刻度可能不够,时钟只有60个刻度,任务可能10分钟以后而不是1分钟以内
-
解决思路
- 超出时间可以给每个任务加一个count,表示该任务要轮多少圈后才能执行,时间轮转一圈就把count-1到0就说明可以执行了
-
最优方案:多级时间轮
- 第一个时间轮表示任务在那个小时执行
- 第二个时间轮表示任务在那一分钟执行
- 第三个时间轮表示任务在那一秒钟执行
- 任务先放在时轮,当小时刻度到了就把任务跃迁到分轮上去,之后再移动到秒轮,再等到准确之间进行执行
高可用问题
单点故障问题
数据库行锁问题
分布式锁问题
调度器Scheduler
资源来源
资源调度
节点选择
广播执行:比如要求所有节点清理运行日志
任务分片
通过任务分片来提高任务执行的效率和资源的利用率
任务编排
故障转移
故障转移:确保部分执行单元任务失败时,任务最终成功
高可用
执行器Executor
- 机器注册:把自己注册进调度中心,让调度中心知道有这样一个机器可以用于调度
- 基于注册中心,当机器启动时可以将其注册进调度中心,这样调度中心就发现多了一台机器可以用于调度