需求背景
目前各服务里经常会有定时任务相关需求,而定时任务通常要求同时只有一个任务执行,为了保证定时任务高可以通常也需要主备部署,导致开发定义任务时需要考虑锁竞争关系,以及考虑任务执行状态(成功、失败、重试等)。因此考虑实现一个统一的分布式任务调度服务,解决如下问题:
- 支持一次性执行任务(一次性任务可以延迟执行);
- 支持cron方式定时执行任务;
- 任务分布式执行,高可用支持;
- 支持简单任务状态统一监控(记录执行状态);
- 支持任务重试机制。
- 技术调研&选型
machinery(开源分布式任务调度框架)
machinery 是一个基于消息队列的分布式任务调度框架,由Server、broker、worker、backend 这么几个概念组成:
- Server:业务模块,生成具体任务,可根据业务逻辑中,按交互进行拆分;
Broker:存储具体序列化后的任务,machinery中目前支持到Redis, AMQP,和SQS;
Worker:工作进程,负责消费者功能,处理具体的任务;
Backend:后端存储,用于存储任务执行状态的数据;
使用使用Server 作为任务生产和任务触发,backend 用作任务运行状态结果存储, machinery分布式框架不能满足定时触发的需求,因此还需要引入cron 定时任务框架,该定时任务框架是基于本地时间的定时任务框架,因此还需要结合分布式锁来保证同时只能触发一次任务。因此整体设计方案大致如下:
由上图我们可以看到系统主要由2部分组成,分布式任务中心和客户端。
分布式任务中心
分布式任务中心用来管理任务、监控、调度、监听任务执行结果等。
- 任务管理:增删查改定时执行任务
- 定时任务监控:监控新的待执行任务,发现后创建新的触发器,失效删除后的定时任务配置
- 推送待执行的任务到消息队列
- 监听任务执行结果
- 接收客户端主动触发推过来的异步任务。
客户端
客户端是分布式任务执行的组成单元,通过监听自己能执行的任务队列,来执行任务
- 任务接收器:接收到任务后将任务分配给worker执行
- 任务执行woker: 负责执行具体的任务
- 执行结果推送:将任务执行结果推送到消息队列
- 一致性任务触发: 部署异步任务只需满足某个条件时,就触发到消息队列中。
任务参数
任务参数1: {“name”:“task1”,“params”:[“params1=x1”,“params2=x2”], “cron_time”:“*/1 * * * ?”}