README.md 19.8 KB
Newer Older
X
xueli.xue 已提交
1 2 3 4 5
# 《分布式任务调度平台xxl-job》
## 一 简介
XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。

#### 1.1 下载
X
xueli.xue 已提交
6 7
源码地址

X
xueli.xue 已提交
8 9
- github地址:https://github.com/xuxueli/xxl-job
- git.osc地址:http://git.oschina.net/xuxueli0323/xxl-job
X
xueli.xue 已提交
10
- 我将会在两个git仓库同步发布最新代码;用户手册放置在源码“/doc”目录下( https://github.com/xuxueli/xxl-job/tree/master/doc );开箱即用;
X
init  
xueli.xue 已提交
11

X
xueli.xue 已提交
12 13
博客地址

X
xueli.xue 已提交
14 15 16 17
- oschina地址:http://my.oschina.net/xuxueli/blog/690978
- cnblogs地址:http://www.cnblogs.com/xuxueli/p/5021979.html
- csdn地址:http://blog.csdn.net/xuxueli0323/article/details/51674330

X
xueli.xue 已提交
18
技术交流群(仅作技术交流):367260654    [![image](http://pub.idqqimg.com/wpa/images/group.png)](http://shang.qq.com/wpa/qunwpa?idkey=4686e3fe01118445c75673a66b4cc6b2c7ce0641528205b6f403c179062b0a52 )
X
xueli.xue 已提交
19

X
xueli.xue 已提交
20
#### 1.2 特性
X
xueli.xue 已提交
21 22 23
- 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;
- 2、动态:支持动态修改任务状态、暂停/恢复任务,以及终止运行中任务,即时生效;
- 3、调度HA:“调度中心”基于集群Quartz实现,可保证调度中心HA;
24 25 26 27 28 29 30 31 32
- 4、任务HA:任务支持多地址配置,可保证任务执行HA;
- 5、任务Failover:多地址配置时,调度失败时将会平滑切换执行器进行Failover;
- 6、一致性:“调度中心”通过DB锁保证集群分布式调度的一致性;
- 7、自定义任务参数:支持在线配置调度任务入参,即时生效;
- 8、调度线程池:调度系统多线程触发调度运行,确保调度精确执行,不被堵塞;
- 9、执行日志:支持在线查看调度结果,并且查看完整的执行日志;
- 10、邮件报警:任务失败时支持邮件报警,同时可自定义失败次数阀值;
- 11、支持登录验证;
- 12、GLUE:提供Web IDE,支持在线开发任务逻辑代码,动态发布,实时编译生效,省略部署上线的过程。
X
xueli.xue 已提交
33 34 35 36 37 38 39 40 41 42

#### 1.3 发展
于2015年中,我在github上创建XXL-JOB项目仓库并提交第一个commit,随之进行系统结构设计,UI选型,交互设计……

于2015-11月,XXL-JOB终于REALEASE了第一个大版本V1.0, 随后我将之发布到OSCHINA,XXL-JOB在OSCHINA上获得了@红薯的热门推荐,同期分别达到了OSCHINA的“热门动弹”排行第一和git.oschina的开源软件月热度排行第一,在此特别感谢红薯,感谢大家的关注和支持。

于2015-12月,我将XXL-JOB发表到我司内部知识库,并且得到内部同事认可。

于2016-01月我司展开XXL-JOB的内部接入和定制工作,在此感谢袁某和尹某两位同事的贡献,同时也感谢内部其他给与关注与支持的同事。

X
xueli.xue 已提交
43
**我司大众点评目前已接入XXL-JOB,内部别名《Ferrari》(Ferrari基于XXL-JOB的V1.1版本定制而成,新接入应用推荐升级最新版本V1.3)**。自2016-01-21接入至2016-05-20为止进行统计,该系统已调度40000余次,表现优异。新接入应用推荐使用最新版本V1.3,因为经过两个大版本的更新,系统的任务模型、UI交互模型以及底层调度通讯模型都有了较大的提升,核心功能更加稳定高效。
X
xueli.xue 已提交
44

X
xueli.xue 已提交
45
至今,XXL-JOB已接入多家公司的线上产品线,接入场景如电商业务,O2O业务和大数据作业等,截止2016-07-19为止,XXL-JOB已接入的公司包括不限于:
X
xueli.xue 已提交
46 47 48 49 50 51
    
	- 1、大众点评;
	- 2、山东学而网络科技有限公司;
	- 3、安徽慧通互联科技有限公司;
	- 4、人人聚财金服;
	- 5、上海棠棣信息科技股份有限公司
X
xueli.xue 已提交
52 53 54
	- 6、运满满
	- 7、米其林(中国区)
	- 8、妈妈联盟
X
xueli.xue 已提交
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
	- ……

欢迎大家的关注和使用,XXL-JOB也将拥抱变化,持续发展。

#### 1.4 接入登记
更多接入公司,欢迎在https://github.com/xuxueli/xxl-job/issues/1 登记。

#### 1.5 报告问题
XXL-JOB托管在Github上,如有问题可在ISSUES上提问,也可以加入技术交流群(仅作技术交流):367260654 。

#### 1.6 源码目录说明
- /xxl-job-admin					【调度中心】:负责管理调度信息,按照调度配置发出调度请求;
- /xxl-job-core					公共依赖
- /xxl-job-executor-example	【执行器】:负责接收调度请求并执行任务逻辑;
- /db		建表脚本
- /doc	用户手册

## 二 总体设计

#### 2.1 架构图
![XXL-JOB架构图](https://static.oschina.net/uploads/img/201606/14125314_NHk8.png "XXL-JOB架构图")

#### 2.2 设计思想
将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。

将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。

因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性;

#### 2.3 系统组成
**调度模块(调度中心)**:负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块;

支持可视化、简单且动态的维管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。

**执行模块(执行器)**:负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;

支持接收“调度中心”的执行请求、终止请求和日志请求等。

## 三 实现原理
#### 3.1 quartz的不足
Quartz作为开源作业调度中的佼佼者,是作业调度的首选。但是集群环境中Quartz采用API的方式对任务进行管理,从而可以避免上述问题,但是同样存在以下问题:
    - 问题一:调用API的的方式操作任务,不人性化;
    - 问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
    - 问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况加,此时调度系统的性能将大大受限于业务;

XXL-JOB的调度中心基于Quartz实现,弥补了quartz的上述不足之处。

#### 3.2 RemoteHttpJobBean
常规Quartz的开发,任务逻辑一般维护在QuartzJobBean中,耦合很严重。XXL-JOB中“调度模块”和“任务模块”完全解耦,调度模块中的所有调度任务使用同一个QuartzJobBean,即RemoteHttpJobBean。不同的调度任务将各自参数维护在各自扩展表数据中,当触发RemoteHttpJobBean执行时,将会解析不同的任务参数发起远程调用,调用各自的远程执行器服务。这种调用模型类似RPC调用,RemoteHttpJobBean提供调用代理的功能,而执行器提供远程服务的功能。

#### 3.3 调度中心HA(集群)
基于Quartz的集群方案,数据库选用Mysql;集群分布式并发环境中使用QUARTZ定时任务调度,会在各个节点会上报任务,存到数据库中,执行时会从数据库中取出触发器来执行,如果触发器的名称和执行时间相同,则只有一个节点去执行此任务。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125524_GxS9.png "在这里输入图片标题")

#### 3.4 调度线程池
默认线程池中线程的数量为10个,避免单线程因阻塞而引起任务调度延迟。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125549_0Knr.png "在这里输入图片标题")

#### 3.5 @DisallowConcurrentExecution
XXL-JOB调度模块的“调度中心”默认不使用该注解,即默认开启并行机制,因为RemoteHttpJobBean为公共QuartzJobBean,这样在多线程调度的情况下,调度模块被阻塞的几率很低,大大提高了调度系统的承载量。

XXL-JOB的每个调度任务虽然在调度模块是并行调度执行的,但是任务调度传递到任务模块的“执行器”确实串行执行的,同时支持任务终止。

#### 3.6 日志回调服务
调度模块的“调度中心”作为Web服务单独部署,除此之外,内部嵌入jetty服务器提供日志回调服务。

“执行器”在接收到任务执行请求后,执行任务,在执行结束之后会将执行结果回调通知“调度中心”,如下图所示。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125628_qON8.png "在这里输入图片标题")

#### 3.7 任务HA(Failover)
如下图所示,任务“执行器地址”支持配置多个,用逗号分隔,如“127.0.0.1:9998,127.0.0.1:9999”。如果任务配置多个执行器地址,当调度中心每次发起调度请求时,会按照地址配置的顺序依次对执行器发出心跳检测请求,第一个检测为存活状态的执行器将会被选定。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125648_7kTR.png "在这里输入图片标题")

调度成功后,可在日志监控界面查看执行日志;

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125703_xKWj.png "在这里输入图片标题")

调度日志显示,任务配置的地址“227.0.0.1:9999,127.0.0.1:9999”,首先对第一个执行器地址“227.0.0.1:9999”进行心跳检测,心跳失败因此跳过;然后对第二个执行器地址“127.0.0.1:9999”进行心跳检测,心跳检测成功,选定为“目标执行器”;然后对“目标执行器”发送调度请求,调度流程结束,等待执行器回调执行结果。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125738_xpGk.png "在这里输入图片标题")

#### 3.8 调度日志组成
调度中心每次进行任务调度,都会记录一条任务日志,任务日志主要包括以下三部分内容:
    - A、任务信息:包括“执行器地址”、“JobHandler”和“执行参数”等属性,根据这些参数,可以精确的定位任务执行的具体机器和任务代码;
    - B、调度信息:包括“调度时间”、“调度结果”和“调度日志”等,根据这些参数,可以了解“调度中心”发起调度请求时具体情况。
    - C、执行信息:包括“执行时间”、“执行结果”和“执行日志”等,根据这些参数,可以了解在“执行器”端任务执行的具体情况;

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125801_9yfn.png "在这里输入图片标题")

#### 3.9 Bean模式任务
开发步骤:
    - 1、开发一个继承“IJobHandler”的实现类,任务逻辑写在execute方法中;
    - 2、将任务类装配到Spring中,例如加 “@Service” 注解;
    - 3、在任务类上加 “@JobHander” 注解,定义注解的name属性值;
    (步骤3中定义的name属性值,在配置Bean模式任务时会用到)

原理:
    每个Bean模式任务都是一个Spring的Bean类实例,它被维护在“执行器”项目的Spring容器中。任务类需要加“@JobHander(name="名称")”注解,因为“执行器”会根据该注解识别Spring容器中的任务。任务类需要继承统一接口“IJobHandler”,任务逻辑在execute方法中开发,因为“执行器”在接收到调度中心的调度请求时,将会调用“IJobHandler”的execute方法,执行任务逻辑。

#### 3.10 GLUE模式任务
开发步骤:GLUE模式任务的开发步骤比较简单,进入GLUE编辑界面,在Demo任务代码的execute方法中写入任务逻辑即可;可使用@Resource或@Autoward注解注入“执行器”项目中的Spring服务;

原理:每个Glue任务的代码,实际上是“一个继承自“IJobHandler”的实现类的类代码”,“执行器”接收到“调度中心”的调度请求时,会通过Groovy类加载器加载此代码,实例化成Java对象,同时注入此代码中声明的Spring服务(请确保Glue代码中的服务和类引用在“执行器”项目中存在),然后调用该对象的execute方法,执行任务逻辑。

#### 3.11 执行器
执行器实际上是一个内嵌的Jetty服务器,默认端口9999。

在项目启动时,执行器会通过“@JobHander”识别Spring容器中“Bean模式任务”,以注解的name属性为key管理起来。

“执行器”接收到“调度中心”的调度请求时,如果任务类型为“Bean模式”,将会匹配Spring容器中的“Bean模式任务”,然后调用其execute方法,执行任务逻辑。如果任务类型为“GLUE模式”,将会加载GLue代码,实例化Java对象,注入依赖的Spring服务(注意:Glue代码中注入的Spring服务,必须存在与该“执行器”项目的Spring容器中),然后调用execute方法,执行任务逻辑。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125907_Eajh.png "在这里输入图片标题")

#### 3.12 任务日志
XXL-JOB会为每次调度请求生成一个单独的日志文件,通过重写LOG4J的Appender实现如下图的数据1处,“调度中心”查看执行日志时将会加载对应的日志文件。

需要注意的是,“执行器”中日志Appender上配置的包名(如下图数据3处),需要覆盖到所有任务(Bean模式 + GLUE模式)的包名,否则覆盖不到的任务将不会生成日志文件。

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125931_Digy.png "在这里输入图片标题")

单独日志文件存放的位置可在“执行器”的log.xml文件进行自定义,如上图中的数字2的位置所示,默认位置为项目磁盘根目录下“/logs/xxl-job/”;

目录格式为:/logs/xxl-job/ “格式化日期”/“数据库调度日志记录的主键ID . log”。

#### 3.13 系统截图
登陆截图:

![输入图片说明](https://static.oschina.net/uploads/img/201606/14125958_3lh1.png "在这里输入图片标题")

任务列表:

![输入图片说明](https://static.oschina.net/uploads/img/201606/14130011_B19K.png "在这里输入图片标题")

任务配置截图:

![输入图片说明](https://static.oschina.net/uploads/img/201606/14130021_CeGE.png "在这里输入图片标题")

在线开发任务GLUE代码,Wed IDE截图:

![输入图片说明](https://static.oschina.net/uploads/img/201606/14130036_tZPO.png "在这里输入图片标题")


## 四 版本更新
#### 4.1 版本 V1.1.x,新特性
X
xueli.xue 已提交
203 204
**【于V1.1.x版本,XXL-JOB正式应用于我司,内部定制别名为 “Ferrari”,新接入应用推荐使用最新版本V1.3.x】**

X
xueli.xue 已提交
205 206 207 208 209 210 211 212
- 1、简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;
- 2、动态:支持动态修改任务状态,动态暂停/恢复任务,即时生效;
- 3、服务HA:任务信息持久化到mysql中,Job服务天然支持集群,保证服务HA;
- 4、任务HA:某台Job服务挂掉,任务会平滑分配给其他的某一台存活服务,即使所有服务挂掉,重启时或补偿执行丢失任务;
- 5、一个任务只会在其中一台服务器上执行;
- 6、任务串行执行;
- 7、支持自定义参数;
- 8、支持远程任务执行终止;
X
init  
xueli.xue 已提交
213

X
xueli.xue 已提交
214
#### 4.2 版本 V1.2.x,新特性
X
xueli.xue 已提交
215 216 217 218 219
- 1、支持任务分组;
- 2、支持“本地任务”、“远程任务”;
- 3、底层通讯支持两种方式,Servlet方式 + JETTY方式;
- 4、支持“任务日志”;
- 5、支持“串行执行”,并行执行;
X
xueli.xue 已提交
220
	
X
init  
xueli.xue 已提交
221
	说明:V1.2版本将系统架构按功能拆分为:
X
xueli.xue 已提交
222 223 224 225
	
		- 调度模块(调度中心):负责管理调度信息,按照调度配置发出调度请求;
		- 执行模块(执行器):负责接收调度请求并执行任务逻辑;
		- 通讯模块:负责调度模块和任务模块之间的信息通讯;
X
init  
xueli.xue 已提交
226
	优点:
X
xueli.xue 已提交
227 228 229 230
	
		- 解耦:任务模块提供任务接口,调度模块维护调度信息,业务相互独立;
		- 高扩展性;
		- 稳定性;
X
xueli.xue 已提交
231

X
xueli.xue 已提交
232
#### 4.3 版本 V1.3.0,新特性
X
xueli.xue 已提交
233 234 235 236
- 1、遗弃“本地任务”模式,推荐使用“远程任务”,易于系统解耦,任务对应的JobHander统称为“执行器”;
- 2、遗弃“servlet”方式底层系统通讯,推荐使用JETTY方式,调度+回调双向通讯,重构通讯逻辑;
- 3、UI交互优化:左侧菜单展开状态优化,菜单项选中状态优化,任务列表打开表格有压缩优化;
- 4、【重要】“执行器”细分为:BEAN、GLUE两种开发模式,简介见下文:
X
xueli.xue 已提交
237
	
X
xueli.xue 已提交
238 239 240 241 242
	“执行器” 模式简介:
		- BEAN模式执行器:每个执行器都是Spring的一个Bean实例,XXL-JOB通过注解@JobHander识别和调度执行器;
		 -GLUE模式执行器:每个执行器对应一段代码,在线Web编辑和维护,动态编译生效,执行器负责加载GLUE代码和执行;

#### 4.4 版本 V1.3.1,新特性	
X
xueli.xue 已提交
243
- 1、更新项目目录结构:
X
xueli.xue 已提交
244 245 246 247 248
	- /xxl-job-admin -------------------- 【调度中心】:负责管理调度信息,按照调度配置发出调度请求;
	- /xxl-job-core ----------------------- 公共依赖
	- /xxl-job-executor-example ------ 【执行器】:负责接收调度请求并执行任务逻辑;
	- /db ---------------------------------- 建表脚本
	- /doc --------------------------------- 用户手册
X
xueli.xue 已提交
249 250
- 2、在新的目录结构上,升级了用户手册;
- 3、优化了一些交互和UI;
X
xueli.xue 已提交
251 252

#### 4.5 版本 V1.3.2,新特性	
X
xueli.xue 已提交
253 254 255
- 1、调度逻辑进行事务包裹;
- 2、执行器异步回调执行日志;
- 3、【重要】在 “调度中心” 支持HA的基础上,扩展执行器的Failover支持,支持配置多执行期地址;
X
xueli.xue 已提交
256

X
xueli.xue 已提交
257
#### 4.6 版本 V1.4.0 新特性
X
coding  
xueli.xue 已提交
258 259 260
- 1、执行器底层实现代码进行重度重构, 优化底层建表脚本;
- 2、执行器中任务线程分组逻辑优化: 之前根据执行器JobHandler进行线程分组,当多个任务复用Jobhanlder会导致相互阻塞。现改为根据调度中心任务进行任务线程分组,任务与任务执行相互隔离;
- 3、执行器调度通讯方案优化, 通过Hex + HC实现建议RPC通讯协议, 优化了通讯参数的维护和解析流程;
X
coding  
xueli.xue 已提交
261 262 263 264 265 266 267 268 269 270
- 4、调度中心, 新建/编辑任务, 界面属性调整: 
    - 4.1、任务新增/编辑界面中去除 "任务名JobName"属性 ,该属性改为系统自动生成: 该字段之前主要用于在 "调度中心" 唯一标示一个任务, 现实意义不大, 因此计划淡化掉该字段,改为系统生成UUID,从而简化任务新建的操作;
    - 4.2、任务新增/编辑界面中去除 "GLUE模式" 复选框位置调整, 改为贴近"JobHandler"输入框右侧;
    - 4.3、任务新增/编辑界面中去除 "报警阈值" 属性;
- 5、问题修复:
    - 5.1、执行器jetty关闭优化,解决一处可能导致jetty无法关闭的问题;
    - 5.2、执行器任务终止时,执行队列回调优化,解决一处导致任务无法回调的问题;
    - 5.3、调度中心中列表分页参数优化,解决一处因服务器限制post长度而引起的问题;
    - 5.4、执行器Jobhandler注解优化,解决一处因事务代理导致的容器无法加载JobHandler的问题;
    - 5.5、远程调度优化,禁用retry策略,解决一处可能导致重复调用的问题;
X
xueli.xue 已提交
271

X
coding  
xueli.xue 已提交
272
Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段, 地址见分支 [V1.3](https://github.com/xuxueli/xxl-job/tree/v1.3) 。新特性将会在master分支持续更新。
X
xueli.xue 已提交
273

X
xueli.xue 已提交
274
#### 规划中
X
coding  
xueli.xue 已提交
275
- 1、任务依赖: 通过事件触发方式实现, 任务执行成功并回调SUCCESS时, 会主动触发一次依赖任务的调度;
X
xueli.xue 已提交
276
- 2、任务执行规则自定义:假如前一个任务正在执行,后续调度执行规则支持自定义;
X
xueli.xue 已提交
277 278 279
		串行(默认,当前逻辑):后续调度入调度队列;
		并行:后续调度并行执行;
		Pass:后续调度被Pass;
X
xueli.xue 已提交
280
- 3、兼容oracle;
X
xueli.xue 已提交
281