概述
XXL-JOB是一個(gè)輕量級(jí)分布式任務(wù)調(diào)度平臺(tái)泳姐,其核心設(shè)計(jì)目標(biāo)是開(kāi)發(fā)迅速、學(xué)習(xí)簡(jiǎn)單暂吉、輕量級(jí)仗岸、易擴(kuò)展≡使ⅲ現(xiàn)已開(kāi)放源代碼并接入多家公司線上產(chǎn)品線,開(kāi)箱即用扒怖。
官方地址中文版:http://www.xuxueli.com/xxl-job
目前已有多家公司接入xxl-job较锡,包括比較知名的大眾點(diǎn)評(píng),京東盗痒,優(yōu)信二手車蚂蕴,北京尚德,360金融 (360)俯邓,聯(lián)想集團(tuán) (聯(lián)想)骡楼,易信 (網(wǎng)易)等等....
Quartz作為開(kāi)源作業(yè)調(diào)度中的佼佼者,是作業(yè)調(diào)度的首選稽鞭。集群環(huán)境中Quartz采用API的方式對(duì)任務(wù)進(jìn)行管理鸟整,Quartz存在以下問(wèn)題:
Quartz的不足
問(wèn)題一:調(diào)用API的的方式操作任務(wù),不人性化朦蕴;
問(wèn)題二:需要持久化業(yè)務(wù)QuartzJobBean到底層數(shù)據(jù)表中篮条,系統(tǒng)侵入性相當(dāng)嚴(yán)重。
問(wèn)題三:調(diào)度邏輯和QuartzJobBean耦合在同一個(gè)項(xiàng)目中吩抓,這將導(dǎo)致一個(gè)問(wèn)題涉茧,在調(diào)度任務(wù)數(shù)量逐漸增多,同時(shí)調(diào)度任務(wù)邏輯逐漸加重的情況加疹娶,此時(shí)調(diào)度系統(tǒng)的性能將大大受限于業(yè)務(wù)伴栓;
問(wèn)題四:quartz底層以“搶占式”獲取DB鎖并由搶占成功節(jié)點(diǎn)負(fù)責(zé)運(yùn)行任務(wù),會(huì)導(dǎo)致節(jié)點(diǎn)負(fù)載懸殊非常大雨饺;而XXL-JOB通過(guò)執(zhí)行器實(shí)現(xiàn)“協(xié)同分配式”運(yùn)行任務(wù)钳垮,充分發(fā)揮集群優(yōu)勢(shì),負(fù)載各節(jié)點(diǎn)均衡额港。
XXL-JOB彌補(bǔ)了quartz的上述不足之處饺窿。
XXL-JOB特性
- 簡(jiǎn)單:支持通過(guò)Web頁(yè)面對(duì)任務(wù)進(jìn)行CRUD操作,操作簡(jiǎn)單锹安,一分鐘上手
- 動(dòng)態(tài):支持動(dòng)態(tài)修改任務(wù)狀態(tài)短荐、啟動(dòng)/停止任務(wù),以及終止運(yùn)行中任務(wù)叹哭,即時(shí)生效
- 調(diào)度中心HA(中心式):調(diào)度采用中心式設(shè)計(jì)忍宋,“調(diào)度中心”基于集群Quartz實(shí)現(xiàn)并支持集群部署,可保證調(diào)度中心HA
- 執(zhí)行器HA(分布式):任務(wù)分布式執(zhí)行风罩,任務(wù)"執(zhí)行器"支持集群部署糠排,可保證任務(wù)執(zhí)行HA
- 注冊(cè)中心: 執(zhí)行器會(huì)周期性自動(dòng)注冊(cè)任務(wù), 調(diào)度中心將會(huì)自動(dòng)發(fā)現(xiàn)注冊(cè)的任務(wù)并觸發(fā)執(zhí)行。同時(shí)超升,也支持手動(dòng)錄入執(zhí)行器地址
- 彈性擴(kuò)容縮容:一旦有新執(zhí)行器機(jī)器上線或者下線入宦,下次調(diào)度時(shí)將會(huì)重新分配任務(wù)
- 路由策略:執(zhí)行器集群部署時(shí)提供豐富的路由策略哺徊,包括:第一個(gè)、最后一個(gè)乾闰、輪詢落追、隨機(jī)、一致性HASH涯肩、最不經(jīng)常使用轿钠、最近最久未使用、故障轉(zhuǎn)移病苗、忙碌轉(zhuǎn)移等
- 故障轉(zhuǎn)移:任務(wù)路由策略選擇"故障轉(zhuǎn)移"情況下疗垛,如果執(zhí)行器集群中某一臺(tái)機(jī)器故障,將會(huì)自動(dòng)Failover切換到一臺(tái)正常的執(zhí)行器發(fā)送調(diào)度請(qǐng)求硫朦。
- 阻塞處理策略:調(diào)度過(guò)于密集執(zhí)行器來(lái)不及處理時(shí)的處理策略贷腕,策略包括:?jiǎn)螜C(jī)串行(默認(rèn))、丟棄后續(xù)調(diào)度咬展、覆蓋之前調(diào)度
- 任務(wù)超時(shí)控制:支持自定義任務(wù)超時(shí)時(shí)間泽裳,任務(wù)運(yùn)行超時(shí)將會(huì)主動(dòng)中斷任務(wù)
- 任務(wù)失敗重試:支持自定義任務(wù)失敗重試次數(shù),當(dāng)任務(wù)失敗時(shí)將會(huì)按照預(yù)設(shè)的失敗重試次數(shù)主動(dòng)進(jìn)行重試挚赊;其中分片任務(wù)支持分片粒度的失敗重試
- 任務(wù)失敗告警诡壁;默認(rèn)提供郵件方式失敗告警济瓢,同時(shí)預(yù)留擴(kuò)展接口荠割,可方便的擴(kuò)展短信、釘釘?shù)雀婢绞?/li>
- 分片廣播任務(wù):執(zhí)行器集群部署時(shí)旺矾,任務(wù)路由策略選擇"分片廣播"情況下蔑鹦,一次任務(wù)調(diào)度將會(huì)廣播觸發(fā)集群中所有執(zhí)行器執(zhí)行一次任務(wù),可根據(jù)分片參數(shù)開(kāi)發(fā)分片任務(wù)
- 動(dòng)態(tài)分片:分片廣播任務(wù)以執(zhí)行器為維度進(jìn)行分片箕宙,支持動(dòng)態(tài)擴(kuò)容執(zhí)行器集群從而動(dòng)態(tài)增加分片數(shù)量嚎朽,協(xié)同進(jìn)行業(yè)務(wù)處理;在進(jìn)行大數(shù)據(jù)量業(yè)務(wù)操作時(shí)可顯著提升任務(wù)處理能力和速度
- 事件觸發(fā):除了"Cron方式"和"任務(wù)依賴方式"觸發(fā)任務(wù)執(zhí)行之外柬帕,支持基于事件的觸發(fā)任務(wù)方式哟忍。調(diào)度中心提供觸發(fā)任務(wù)單次執(zhí)行的API服務(wù),可根據(jù)業(yè)務(wù)事件靈活觸發(fā)
- 任務(wù)進(jìn)度監(jiān)控:支持實(shí)時(shí)監(jiān)控任務(wù)進(jìn)度
- Rolling實(shí)時(shí)日志:支持在線查看調(diào)度結(jié)果陷寝,并且支持以Rolling方式實(shí)時(shí)查看執(zhí)行器輸出的完整的執(zhí)行日志
- GLUE:提供Web IDE锅很,支持在線開(kāi)發(fā)任務(wù)邏輯代碼,動(dòng)態(tài)發(fā)布樟氢,實(shí)時(shí)編譯生效贷痪,省略部署上線的過(guò)程烦却。支持30個(gè)版本的歷史版本回溯
- 腳本任務(wù):支持以GLUE模式開(kāi)發(fā)和運(yùn)行腳本任務(wù)家厌,包括Shell扔仓、Python褐奥、NodeJS、PHP翘簇、PowerShell等類型腳本
- 命令行任務(wù):原生提供通用命令行任務(wù)Handler(Bean任務(wù)撬码,"CommandJobHandler");業(yè)務(wù)方只需要提供命令行即可
- 任務(wù)依賴:支持配置子任務(wù)依賴版保,當(dāng)父任務(wù)執(zhí)行結(jié)束且執(zhí)行成功后將會(huì)主動(dòng)觸發(fā)一次子任務(wù)的執(zhí)行, 多個(gè)子任務(wù)用逗號(hào)分隔
- 一致性:“調(diào)度中心”通過(guò)DB鎖保證集群分布式調(diào)度的一致性, 一次任務(wù)調(diào)度只會(huì)觸發(fā)一次執(zhí)行
- 自定義任務(wù)參數(shù):支持在線配置調(diào)度任務(wù)入?yún)⑺H海磿r(shí)生效
- 調(diào)度線程池:調(diào)度系統(tǒng)多線程觸發(fā)調(diào)度運(yùn)行,確保調(diào)度精確執(zhí)行找筝,不被堵塞
- 數(shù)據(jù)加密:調(diào)度中心和執(zhí)行器之間的通訊進(jìn)行數(shù)據(jù)加密蹈垢,提升調(diào)度信息安全性
- 郵件報(bào)警:任務(wù)失敗時(shí)支持郵件報(bào)警,支持配置多郵件地址群發(fā)報(bào)警郵件
- 推送maven中央倉(cāng)庫(kù): 將會(huì)把最新穩(wěn)定版推送到maven中央倉(cāng)庫(kù), 方便用戶接入和使用
- 運(yùn)行報(bào)表:支持實(shí)時(shí)查看運(yùn)行數(shù)據(jù)袖裕,如任務(wù)數(shù)量曹抬、調(diào)度次數(shù)、執(zhí)行器數(shù)量等急鳄;以及調(diào)度報(bào)表谤民,如調(diào)度日期分布圖,調(diào)度成功分布圖等
- 全異步:任務(wù)調(diào)度流程全異步化設(shè)計(jì)實(shí)現(xiàn)疾宏,如異步調(diào)度张足、異步運(yùn)行、異步回調(diào)等坎藐,有效對(duì)密集調(diào)度進(jìn)行流量削峰为牍,理論上支持任意時(shí)長(zhǎng)任務(wù)的運(yùn)行
- 跨平臺(tái):原生提供通用HTTP任務(wù)Handler(Bean任務(wù),"HttpJobHandler")岩馍,業(yè)務(wù)方只需要提供HTTP鏈接即可碉咆,不限制語(yǔ)言、平臺(tái)
- 國(guó)際化:調(diào)度中心支持國(guó)際化設(shè)置蛀恩,提供中文疫铜、英文兩種可選語(yǔ)言,默認(rèn)為中文
- 容器化:提供官方docker鏡像双谆,并實(shí)時(shí)更新推送dockerhub壳咕,進(jìn)一步實(shí)現(xiàn)產(chǎn)品開(kāi)箱即用
- 線程池隔離:調(diào)度線程池進(jìn)行隔離拆分,慢任務(wù)自動(dòng)降級(jí)進(jìn)入"Slow"線程池顽馋,避免耗盡調(diào)度線程谓厘,提高系統(tǒng)穩(wěn)定性
快速入門(mén)
解壓源碼,按照maven格式將源碼導(dǎo)入IDE, 使用maven進(jìn)行編譯即可,源碼結(jié)構(gòu)如下:
xxl-job-admin:調(diào)度中心
xxl-job-core:公共依賴
xxl-job-executor-samples:執(zhí)行器Sample示例(選擇合適的版本執(zhí)行器趣避,可直接使用庞呕,也可以參考其并將現(xiàn)有項(xiàng)目改造成執(zhí)行器)
:xxl-job-executor-sample-springboot:Springboot版本,通過(guò)Springboot管理執(zhí)行器,推薦這種方式住练;
:xxl-job-executor-sample-spring:Spring版本地啰,通過(guò)Spring容器管理執(zhí)行器,比較通用讲逛;
:xxl-job-executor-sample-frameless:無(wú)框架版本亏吝;
:xxl-job-executor-sample-jfinal:JFinal版本,通過(guò)JFinal管理執(zhí)行器盏混;
:xxl-job-executor-sample-nutz:Nutz版本蔚鸥,通過(guò)Nutz管理執(zhí)行器;
1.初始化"調(diào)度數(shù)據(jù)庫(kù)"
到官網(wǎng)下載項(xiàng)目源碼并解壓许赃,獲取 "調(diào)度數(shù)據(jù)庫(kù)初始化SQL腳本" 并執(zhí)行即可止喷,正常情況下應(yīng)該生成16張表。SQL腳本位置:/xxl-job/doc/db/tables_xxl_job.sql
注意??:調(diào)度中心支持集群部署混聊,集群情況下各節(jié)點(diǎn)務(wù)必連接同一個(gè)mysql實(shí)例;
如果mysql做主從,調(diào)度中心集群節(jié)點(diǎn)務(wù)必強(qiáng)制走主庫(kù)
2.部署調(diào)度中心
調(diào)度中心項(xiàng)目:xxl-job-admin
作用:統(tǒng)一管理任務(wù)調(diào)度平臺(tái)上調(diào)度任務(wù)弹谁,負(fù)責(zé)觸發(fā)調(diào)度執(zhí)行,并且提供任務(wù)管理平臺(tái)句喜。
步驟一:調(diào)度中心配置
調(diào)度中心配置文件地址:/xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties
### 調(diào)度中心JDBC鏈接
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl-job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root_pwd
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
### 報(bào)警郵箱
spring.mail.host=smtp.qq.com
spring.mail.port=25
spring.mail.username=xxx@qq.com
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
### 登錄賬號(hào)
xxl.job.login.username=admin
xxl.job.login.password=123456
### 調(diào)度中心通訊TOKEN预愤,用于調(diào)度中心和執(zhí)行器之間的通訊進(jìn)行數(shù)據(jù)加密,非空時(shí)啟用
xxl.job.accessToken=
### 調(diào)度中心國(guó)際化設(shè)置咳胃,默認(rèn)為中文版本植康,值設(shè)置為“en”時(shí)切換為英文版本
xxl.job.i18n=
步驟二:部署項(xiàng)目
如果已經(jīng)正確進(jìn)行上述配置,可將項(xiàng)目編譯打包部署展懈。 調(diào)度中心訪問(wèn)地址:http://localhost:8080/xxl-job-admin (該地址執(zhí)行器將會(huì)使用到销睁,作為回調(diào)地址),登錄后運(yùn)行界面如下圖所示
至此“調(diào)度中心”項(xiàng)目已經(jīng)部署成功标沪。
步驟三:調(diào)度中心集群可選
調(diào)度中心支持集群部署榄攀,提升調(diào)度系統(tǒng)容災(zāi)和可用性嗜傅。
調(diào)度中心集群部署時(shí)金句,幾點(diǎn)要求和建議:
- DB配置保持一致;
- 登陸賬號(hào)配置保持一致吕嘀;
- 集群機(jī)器時(shí)鐘保持一致(單機(jī)集群忽視)违寞;
- 建議:推薦通過(guò)nginx為調(diào)度中心集群做負(fù)載均衡,分配域名偶房。調(diào)度中心訪問(wèn)趁曼、執(zhí)行器回調(diào)配置、調(diào)用API服務(wù)等操作均通過(guò)該域名進(jìn)行棕洋。
3.部署執(zhí)行器項(xiàng)目
執(zhí)行器負(fù)責(zé)接收“調(diào)度中心”的調(diào)度并執(zhí)行挡闰;在源碼中作者已經(jīng)貼心的給出了多種執(zhí)行器項(xiàng)目示例,可根據(jù)你的喜好直接將其部署作為你自己的執(zhí)行器,當(dāng)然你也可以將執(zhí)行器集成到現(xiàn)有業(yè)務(wù)項(xiàng)目中去
現(xiàn)以集成到現(xiàn)有項(xiàng)目為例摄悯,將執(zhí)行器集成到現(xiàn)有的一個(gè)Spring-Boot項(xiàng)目Athena中去
步驟一:在你的項(xiàng)目里引入xxl-job-core的依賴
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.0.1</version>
</dependency>
步驟二:執(zhí)行器配置
將源碼中/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties下的配置信息copy一份赞季,添加到你的項(xiàng)目的application.properties文件中去,注意修改自己的配置信息
### 調(diào)度中心部署跟地址 [選填]:如調(diào)度中心集群部署存在多個(gè)地址則用逗號(hào)分隔奢驯。執(zhí)行器將會(huì)使用該地址進(jìn)行"執(zhí)行器心跳注冊(cè)"和"任務(wù)結(jié)果回調(diào)"申钩;為空則關(guān)閉自動(dòng)注冊(cè);
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### 執(zhí)行器AppName [選填]:執(zhí)行器心跳注冊(cè)分組依據(jù)瘪阁;為空則關(guān)閉自動(dòng)注冊(cè)
xxl.job.executor.appname=xxl-job-executor-athena
### 執(zhí)行器IP [選填]:默認(rèn)為空表示自動(dòng)獲取IP撒遣,多網(wǎng)卡時(shí)可手動(dòng)設(shè)置指定IP,該IP不會(huì)綁定Host僅作為通訊實(shí)用管跺;地址信息用于 "執(zhí)行器注冊(cè)" 和 "調(diào)度中心請(qǐng)求并觸發(fā)任務(wù)"义黎;
xxl.job.executor.ip=
### 執(zhí)行器端口號(hào) [選填]:小于等于0則自動(dòng)獲取豁跑;默認(rèn)端口為9999轩缤,單機(jī)部署多個(gè)執(zhí)行器時(shí),注意要配置不同執(zhí)行器端口贩绕;
xxl.job.executor.port=9999
### 執(zhí)行器通訊TOKEN [選填]:非空時(shí)啟用火的;
xxl.job.accessToken=
### 執(zhí)行器運(yùn)行日志文件存儲(chǔ)磁盤(pán)路徑 [選填] :需要對(duì)該路徑擁有讀寫(xiě)權(quán)限;為空則使用默認(rèn)路徑淑倾;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 執(zhí)行器日志保存天數(shù) [選填] :值大于3時(shí)生效馏鹤,啟用執(zhí)行器Log文件定期清理功能,否則不生效娇哆;
xxl.job.executor.logretentiondays=-1
步驟三:執(zhí)行器組件配置
執(zhí)行器組件配置信息位置:/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java
找到這個(gè)XxlJobConfig.java復(fù)制一份到你的項(xiàng)目里即可
步驟四:部署執(zhí)行器項(xiàng)目
如果已經(jīng)正確進(jìn)行上述配置湃累,可將執(zhí)行器項(xiàng)目編譯打部署,源碼中執(zhí)行器示例項(xiàng)目各自的部署方式如下:
- xxl-job-executor-sample-springboot:項(xiàng)目編譯打包成springboot類型的可執(zhí)行JAR包碍讨,命令啟動(dòng)即可
- xxl-job-executor-sample-spring:項(xiàng)目編譯打包成WAR包治力,并部署到tomcat中
- xxl-job-executor-sample-jfinal:同上
- xxl-job-executor-sample-nutz:同上
至此“執(zhí)行器”項(xiàng)目已經(jīng)部署結(jié)束
步驟五:執(zhí)行器項(xiàng)目集群(可選)
執(zhí)行器支持集群部署,提升調(diào)度系統(tǒng)可用性勃黍,同時(shí)提升任務(wù)處理能力宵统。
執(zhí)行器集群部署時(shí),幾點(diǎn)要求和建議:
- 執(zhí)行器回調(diào)地址(xxl.job.admin.addresses)需要保持一致覆获;執(zhí)行器根據(jù)該配置進(jìn)行執(zhí)行器自動(dòng)注冊(cè)等操作
- 同一個(gè)執(zhí)行器集群內(nèi)AppName(xxl.job.executor.appname)需要保持一致马澈;調(diào)度中心根據(jù)該配置動(dòng)態(tài)發(fā)現(xiàn)不同集群的在線執(zhí)行器列表
4.開(kāi)發(fā)自己的任務(wù)
4.1在執(zhí)行器項(xiàng)目中新建自己的任務(wù),代碼示例:
package com.tp.athena.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import org.springframework.stereotype.Component;
import javax.sound.midi.Soundbank;
import java.util.concurrent.TimeUnit;
/**
* 任務(wù)Handler示例(Bean模式)
* <p>
* 開(kāi)發(fā)步驟:
* 1弄息、繼承"IJobHandler":“com.xxl.job.core.handler.IJobHandler”痊班;
* 2、注冊(cè)到Spring容器:添加“@Component”注解摹量,被Spring容器掃描為Bean實(shí)例涤伐;
* 3馒胆、注冊(cè)到執(zhí)行器工廠:添加“@JobHandler(value="自定義jobhandler名稱")”注解,注解value值對(duì)應(yīng)的是調(diào)度中心新建任務(wù)的JobHandler屬性的值凝果。
* 4国章、執(zhí)行日志:需要通過(guò) "XxlJobLogger.log" 打印執(zhí)行日志;
*
* @author xuxueli 2015-12-19 19:43:36
*/
@JobHandler(value = "demoJobHandler")
@Component
public class DemoJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
System.out.println("XXL-JOB Hello World");
return SUCCESS;
}
}
4.2在調(diào)度中心新建任務(wù)
登錄調(diào)度中心豆村,點(diǎn)擊下圖所示“新建任務(wù)”按鈕液兽,新建示例任務(wù)。然后掌动,參考下面截圖中任務(wù)的參數(shù)配置四啰,點(diǎn)擊保存。
點(diǎn)擊保存
點(diǎn)擊右側(cè)啟動(dòng)此任務(wù)粗恢,將任務(wù)啟動(dòng)
4.3啟動(dòng)調(diào)度中心柑晒,啟動(dòng)執(zhí)行器項(xiàng)目
效果如下:
在調(diào)度中心我們可以查看調(diào)度日志