这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
核心架构
- Trigger 触发器
- Scheduler 调度器
- Executor 执行器
- Admin 控制台
数据流
任务创建:用户添加任务基础信息、设置触发规则(时间、事件等)、任务代码,提交至 Admin,存储至任务数据库内。
任务执行:触发器触发任务->调度器调度任务->执行器执行任务
这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记
功能架构
Admin
元数据存储、元数据状态流转、任务分片、任务以来、规则引擎、任务暂停/恢复、日志管理、监控报警、指标统计...
Job:任务元数据。基础信息、调度时机、执行行为、执行方式。
JobInstance:任务运行的实例(一个任务可以有多个运行实例)。Job_id、触发事件、状态&结果、过程信息(消息id等)
JobResult:任务实例运行结果(一个任务实例可以有多个结果)
JobHistory:任务历史(一个任务可以用多个不同的任务信息,任务历史存储任务信息修改历史)
Trigger
解析引擎、Scanner(扫描数据库中的任务)、可靠投递(Processor,借助消息队列)、状态流转、补偿策略...
设计约束
- 大量任务
- 秒级调度
- 周期执行
- 避免浪费
定时扫描、延时消息方案
Scanner 从 DB 中扫描任务,扫描后添加至 Processor 处理,Processor 交给消息队列(延时 MQ)
时间轮方案
使用环形数组存储任务列表。
缺点:环形数组刻度、能表示的时间有限
解决方案:添加 count(经过 count 轮再执行当前刻度的任务)。多级时间轮:秒轮、分轮、时轮
优点:时间复杂度查询和修改都是 O(1),易于扩展时间尺度、易于理解。
应用广泛,不止应用于此
高可用
避免单点故障,使用多机架构又要避免重复触发
解决方案:多个 Trigger 争夺数据库锁(使用 MySQL 行锁性能较差,使用 Redis 等较优),抢锁成功则调度,失败则放弃
Schedule
调度、负载均衡、幂等控制、容错、故障转移、限流、计费、优雅启停、状态管控...
资源:可供调度器调度的机器资源、内存资源、CPU资源、网络资源等
资源来源
与业务公用资源:利用率高,成本低。但相较下容易发生事故,不能由定时任务平台决定扩缩容。
定时任务平台专用资源:与业务隔离,避免相互影响,可扩缩容。但是成本更高,且需要额外设计和申请接口权限,无法复用业务平台的接口权限。
资源调度
随机节点执行:随机选择 Executor 执行任务
广播执行:所有 Executor 共同执行任务
任务分片:将任务分为 N 段,分别分配给 N 个 Executor
任务编排
使用有向无环图(Directed Asyclic Graph)进行可视化任务编排。
故障转移
单机任务:分配给一个 Executor 失败后就分配给其它机器执行
分片任务:分片任务基于一致性 HASH 策略分配任务,Executor 异常时分发到其它 Executor
高可用
Scheduler 本身无状态,可以进行集群部署。可以多个 Scheduler 从同一 MQ 中读取任务并调度。可以借助 MQ 的重试机制保证任务被调度。
Executor
注册(向调度器注册)、任务获取、任务执行、状态上报、日志处理、本地幂等、任务回调...
...