简体中文
| English
Disjob
Introduction
一个分布式的任务调度框架,除了具备常规的分布式任务调度功能外,还提供任务拆分、暂停/恢复/取消运行中的任务、广播任务、任务依赖、工作流任务(DAG)、管理器与执行器分离部署等能力。
轻量级,简单易用,特别适合长任务的执行。有较好的伸缩性,扩展性,稳定性,历经生产检验。
Architecture
- 架构图
- 工程结构
disjob # 主项目
├── disjob-bom # Maven project bom module
├── disjob-common # 工具包
├── disjob-core # 任务调度相关的核心类(如数据模型、枚举类、抽象层接口等)
├── disjob-dispatch # 任务分发模块
│ ├── disjob-dispatch-api # 任务分发的抽象接口层
│ ├── disjob-dispatch-http # 任务分发的Http实现
│ └── disjob-dispatch-redis # 任务分发的Redis实现
├── disjob-id # 分布式ID生成
├── disjob-registry # Server(Supervisor & Worker)注册模块
│ ├── disjob-registry-api # Server注册的抽象接口层
│ ├── disjob-registry-consul # Server注册的Consul实现
│ ├── disjob-registry-etcd # Server注册的Etcd实现
│ ├── disjob-registry-nacos # Server注册的Nacos实现
│ ├── disjob-registry-redis # Server注册的Redis实现
│ └── disjob-registry-zookeeper # Server注册的Zookeeper实现
├── disjob-reports # 聚合各个模块的测试覆盖率报告
├── disjob-samples # Samples项目
│ ├── disjob-samples-common # 存放使用范例中用到的公共代码,包括使用到的一些公共配置文件等
│ ├── disjob-samples-merged # Supervisor与Worker合并部署的范例(Spring boot应用)
│ └── disjob-samples-separately # Supervisor与Worker分离部署的范例模块
│ ├── disjob-samples-separately-supervisor # Supervisor单独部署的范例(Spring boot应用)
│ ├── disjob-samples-separately-worker-frameless # Worker单独部署的范例(非Spring-boot应用,直接main方法启动)
│ └── disjob-samples-separately-worker-springboot # Worker单独部署的范例(Spring boot应用)
├── disjob-supervisor # Supervisor代码(Spring-boot应用,需要引导Spring扫描该包目录)
├── disjob-test # 用于辅助测试
└── disjob-worker # Worker代码
Features
- 分为管理器(Supervisor)和执行器(Worker)两种角色,Supervisor与Worker可分离部署
- Supervisor与Worker通过注册中心解耦,目前支持的注册中心有:Redis、Consul、Nacos、Zookeeper、Etcd
- Supervisor以任务分发方式把任务给到Worker,目前支持的任务分发方式有:Redis、Http
- 支持任务分组(job-group),任务会分发给指定组的Worker执行
- 自定义拆分任务,重写JobHandler#split即可把一个大任务拆分为多个小任务,任务分治
- 提供任务执行快照的自动保存(checkpoint),让执行信息不丢失,保证因异常中断的任务能得到继续执行
- 提供执行中的任务控制能力,可随时暂停/取消正在执行中的任务,亦可恢复执行被暂停的任务
- 提供任务依赖执行的能力,多个任务构建好依赖关系后,任务便按既定的依赖顺序依次执行
Download From Maven Central
注意: 最近 aliyun 那边的镜像仓受Maven中央仓库网络限制,部分依赖可能会从中央仓库同步文件失败,如果依赖查找不到(即无法下载)请在
settings.xml
文件中删除aliyun mirror的配置(不建议使用aliyun maven mirror)
<dependency>
<groupId>cn.ponfee</groupId>
<artifactId>disjob-{xxx}</artifactId>
<version>1.11</version>
</dependency>
Build From Source
./mvnw clean install -DskipTests -Dcheckstyle.skip=true -U
Quick Start
- IDE分别导入项目(分为两个独立的项目,共用一个Git仓库)
-
运行仓库代码提供的SQL脚本,创建数据库表:mysql-schema.sql(也可直接运行内置mysql-server,启动时会自动初始化SQL脚本)
- 如果使用默认的本地配置(如consul localhost 8500),可无需添加对应的resource配置文件(包括Nacos、Zookeeper、Etcd等)
- 非Spring-boot的Worker应用的配置文件为worker-conf.yml
-
编写自己的任务处理器PrimeCountJobHandler,并继承JobHandler
-
启动samples项目下的各应用,包括
1)disjob-samples-merged # Supervisor与Worker合并部署的Spring boot应用
2)disjob-samples-separately-supervisor # Supervisor单独部署的Spring boot应用
3)disjob-samples-separately-worker-springboot # Worker单独部署的Spring boot应用
4)disjob-samples-separately-worker-frameless # Worker单独部署(非Spring-boot应用),直接运行Main方法启动
- 已配置不同端口,可同时启动(多个Server组成分布式集群调度环境)
- 可以在开发工具中运行启动类,也可直接运行构建好的jar包
- 注册中心及分发任务的具体实现:在pom文件中引入指定的依赖即可
- 项目已内置一些本地启动的server(部分要依赖本地docker环境)
@EnableSupervisor
@EnableWorker
public class MergedApplication extends AbstractSamplesApplication {
public static void main(String[] args) {
SpringApplication.run(MergedApplication.class, args);
}
}
- 执行以下curl命令添加任务(任选一台运行中的Supervisor应用替换
localhost:8081
)
triggerValue
修改为大于当前时间的日期值以便即将触发(如当前时间点的下一分钟)jobHandler
支持:类的全限定名、Spring bean name、DAG表达式、源码
curl --location --request POST 'http://localhost:8081/api/job/add' \
--header 'Content-Type: application/json' \
--data-raw '{
"jobGroup": "default",
"jobName": "prime-counter",
"jobHandler": "cn.ponfee.disjob.samples.common.handler.PrimeCountJobHandler",
"jobState": 1,
"jobParam": "{\"m\":1,\"n\":6000000000,\"blockSize\":100000000,\"parallel\":7}",
"triggerType": 2,
"triggerValue": "2022-10-06 12:00:00"
}'
- 查询库表验证任务是否添加成功,以及可查看任务的执行信息
-- 刚CURL添加的任务会落入该表中
SELECT * FROM sched_job;
-- 查看任务的执行信息
SELECT * from sched_instance;
SELECT * from sched_task;
-- 可执行以下SQL让该JOB再次触发执行
UPDATE sched_job SET job_state=1, last_trigger_time=NULL, next_trigger_time=(unix_timestamp()*1000+2000) WHERE job_name='prime-counter';
- 也可执行以下CURL命令手动触发执行一次(任选一台运行中的Supervisor替换
localhost:8081
,jobId替换为待触发执行的job)
curl --location --request POST 'http://localhost:8081/api/job/trigger?jobId=4236701614080' \
--header 'Content-Type: application/json'
Contributing
如有发现bug、更优的实现方案、新特性等,可提交PR或新建Issues。
Todo List
- Worker提供任务校验及拆分的Http接口给Supervisor调用(WorkerServiceProvider)
- 扩展注册中心:Zookeeper、Etcd、Nacos
- 工作流任务(Workflow DAG)
- 任务管理后台Web UI、账户体系及权限控制
- 搭建一个关于项目使用说明的文档站点
- 在线查看任务实时运行日志
- 告警订阅:邮件、短信、电话、飞书、钉钉、微信
- 可视化监控BI(Dashboard)
- 增加多种Checkpoint的支持:File System、Hadoop、RocksDB