## 概述
XXL-JOB是一個輕量級分布式任務調度平臺,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼并接入多家公司線上產品線,開箱即用。官方地址中文版:[http://www.xuxueli.com/xxl-job](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.xuxueli.com%2Fxxl-job)目前已有多家公司接入xxl-job,包括比較知名的大眾點評,京東,優信二手車,北京尚德,360金融 (360),聯想集團 (聯想),易信 (網易)等等....Quartz作為開源作業調度中的佼佼者,是作業調度的首選。集群環境中Quartz采用API的方式對任務進行管理,Quartz存在以下問題:
## Quartz的不足
問題一:調用API的的方式操作任務,不人性化;問題二:需要持久化業務QuartzJobBean到底層數據表中,系統侵入性相當嚴重。問題三:調度邏輯和QuartzJobBean耦合在同一個項目中,這將導致一個問題,在調度任務數量逐漸增多,同時調度任務邏輯逐漸加重的情況加,此時調度系統的性能將大大受限于業務;問題四:quartz底層以“搶占式”獲取DB鎖并由搶占成功節點負責運行任務,會導致節點負載懸殊非常大;而XXL-JOB通過執行器實現“協同分配式”運行任務,充分發揮集群優勢,負載各節點均衡。XXL-JOB彌補了quartz的上述不足之處。
## XXL-JOB特性
* 簡單:支持通過Web頁面對任務進行CRUD操作,操作簡單,一分鐘上手
* 動態:支持動態修改任務狀態、啟動/停止任務,以及終止運行中任務,即時生效
* 調度中心HA(中心式):調度采用中心式設計,“調度中心”基于集群Quartz實現并支持集群部署,可保證調度中心HA
* 執行器HA(分布式):任務分布式執行,任務"執行器"支持集群部署,可保證任務執行HA
* 注冊中心: 執行器會周期性自動注冊任務, 調度中心將會自動發現注冊的任務并觸發執行。同時,也支持手動錄入執行器地址
* 彈性擴容縮容:一旦有新執行器機器上線或者下線,下次調度時將會重新分配任務
* 路由策略:執行器集群部署時提供豐富的路由策略,包括:第一個、最后一個、輪詢、隨機、一致性HASH、最不經常使用、最近最久未使用、故障轉移、忙碌轉移等
* 故障轉移:任務路由策略選擇"故障轉移"情況下,如果執行器集群中某一臺機器故障,將會自動Failover切換到一臺正常的執行器發送調度請求。
* 阻塞處理策略:調度過于密集執行器來不及處理時的處理策略,策略包括:單機串行(默認)、丟棄后續調度、覆蓋之前調度
* 任務超時控制:支持自定義任務超時時間,任務運行超時將會主動中斷任務
* 任務失敗重試:支持自定義任務失敗重試次數,當任務失敗時將會按照預設的失敗重試次數主動進行重試;其中分片任務支持分片粒度的失敗重試
* 任務失敗告警;默認提供郵件方式失敗告警,同時預留擴展接口,可方便的擴展短信、釘釘等告警方式
* 分片廣播任務:執行器集群部署時,任務路由策略選擇"分片廣播"情況下,一次任務調度將會廣播觸發集群中所有執行器執行一次任務,可根據分片參數開發分片任務
* 動態分片:分片廣播任務以執行器為維度進行分片,支持動態擴容執行器集群從而動態增加分片數量,協同進行業務處理;在進行大數據量業務操作時可顯著提升任務處理能力和速度
* 事件觸發:除了"Cron方式"和"任務依賴方式"觸發任務執行之外,支持基于事件的觸發任務方式。調度中心提供觸發任務單次執行的API服務,可根據業務事件靈活觸發
* 任務進度監控:支持實時監控任務進度
* Rolling實時日志:支持在線查看調度結果,并且支持以Rolling方式實時查看執行器輸出的完整的執行日志
* GLUE:提供Web IDE,支持在線開發任務邏輯代碼,動態發布,實時編譯生效,省略部署上線的過程。支持30個版本的歷史版本回溯
* 腳本任務:支持以GLUE模式開發和運行腳本任務,包括Shell、Python、NodeJS、PHP、PowerShell等類型腳本
* 命令行任務:原生提供通用命令行任務Handler(Bean任務,"CommandJobHandler");業務方只需要提供命令行即可
* 任務依賴:支持配置子任務依賴,當父任務執行結束且執行成功后將會主動觸發一次子任務的執行, 多個子任務用逗號分隔
* 一致性:“調度中心”通過DB鎖保證集群分布式調度的一致性, 一次任務調度只會觸發一次執行
* 自定義任務參數:支持在線配置調度任務入參,即時生效
* 調度線程池:調度系統多線程觸發調度運行,確保調度精確執行,不被堵塞
* 數據加密:調度中心和執行器之間的通訊進行數據加密,提升調度信息安全性
* 郵件報警:任務失敗時支持郵件報警,支持配置多郵件地址群發報警郵件
* 推送maven中央倉庫: 將會把最新穩定版推送到maven中央倉庫, 方便用戶接入和使用
* 運行報表:支持實時查看運行數據,如任務數量、調度次數、執行器數量等;以及調度報表,如調度日期分布圖,調度成功分布圖等
* 全異步:任務調度流程全異步化設計實現,如異步調度、異步運行、異步回調等,有效對密集調度進行流量削峰,理論上支持任意時長任務的運行
* 跨平臺:原生提供通用HTTP任務Handler(Bean任務,"HttpJobHandler"),業務方只需要提供HTTP鏈接即可,不限制語言、平臺
* 國際化:調度中心支持國際化設置,提供中文、英文兩種可選語言,默認為中文
* 容器化:提供官方docker鏡像,并實時更新推送dockerhub,進一步實現產品開箱即用
* 線程池隔離:調度線程池進行隔離拆分,慢任務自動降級進入"Slow"線程池,避免耗盡調度線程,提高系統穩定性
## 快速入門
解壓源碼,按照maven格式將源碼導入IDE, 使用maven進行編譯即可,源碼結構如下:
xxl-job-admin:調度中心
xxl-job-core:公共依賴
xxl-job-executor-samples:執行器Sample示例(選擇合適的版本執行器,可直接使用)
:xxl-job-executor-sample-springboot:Springboot版本,通過Springboot管理執行器,推薦這種方式;
:xxl-job-executor-sample-spring:Spring版本,通過Spring容器管理執行器,比較通用;
:xxl-job-executor-sample-frameless:無框架版本;
:xxl-job-executor-sample-jfinal:JFinal版本,通過JFinal管理執行器;
:xxl-job-executor-sample-nutz:Nutz版本,通過Nutz管理執行器;
#### **1.初始化"調度數據庫"**
到官網下載項目源碼并解壓,獲取 "調度數據庫初始化SQL腳本" 并執行即可,正常情況下應該生成16張表。SQL腳本位置:/xxl-job/doc/db/tables\_xxl\_job.sql注意??:調度中心支持集群部署,集群情況下各節點務必連接同一個mysql實例;如果mysql做主從,調度中心集群節點務必強制走主庫
#### **2.部署調度中心**
調度中心項目:xxl-job-admin作用:統一管理任務調度平臺上調度任務,負責觸發調度執行,并且提供任務管理平臺。**步驟一:調度中心配置**調度中心配置文件地址:application.properties
~~~
#-------------任務控制臺系統-------------------------
server.port=9003
server.context-path=/hmall-job-admin
### actuator
management.context-path=/actuator
management.health.mail.enabled=false
### resources
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:/static/
### freemarker
spring.freemarker.templateLoaderPath=classpath:/templates/
spring.freemarker.suffix=.ftl
spring.freemarker.charset=UTF-8
spring.freemarker.request-context-attribute=request
spring.freemarker.settings.number_format=0.##########
### mybatis
mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
### xxl-job, datasource
spring.datasource.url=jdbc:mysql://********:3306/hj_mall_job?Unicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=30
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=SELECT 1
spring.datasource.tomcat.validation-interval=30000
### xxl-job email
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
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
### xxl-job, access token
xxl.job.accessToken=
### xxl-job, i18n (default empty as chinese, "en" as english)
xxl.job.i18n=
## xxl-job, triggerpool max size
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100
### xxl-job, log retention days
xxl.job.logretentiondays=30
~~~
**步驟二:部署項目**如果已經正確進行上述配置,可將項目編譯打包部署。 調度中心訪問地址:[http://localhost:8080/hmall-job-admin/](http://localhost:8080/hmall-job-admin/) (該地址執行器將會使用到,作為回調地址),登錄后運行界面如下圖所示

至此“調度中心”項目已經部署成功。
#### **3.部署執行器項目**
```
執行器負責接收“調度中心”的調度并執行;在源碼中作者已經貼心的給出了多種執行器項目示例,可根據你的喜好直接將其部署作為你自己的執行器,當然你也可以將執行器集成到現有業務項目中去
```
**步驟一:在你的項目里引入xxl-job-core的依賴**
~~~
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job-core.version}</version>
</dependency>
~~~
**步驟二:執行器配置**將源碼中/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties下的配置信息copy一份,添加到你的項目的application.properties文件中去,注意修改自己的配置信息
```
xxl:
job:
admin:
addresses: http://127.0.0.1:9003/hj-job-admin ### 調度中心部署跟地址 [選填]:如調度中心集群部署存在多個地址則用逗號分隔。執行器將會使用該地址進行"執行器心跳注冊"和"任務結果回調";為空則關閉自動注冊;
executor:
appname: hmall-job ### 執行器AppName [選填]:執行器心跳注冊分組依據;為空則關閉自動注冊
ip: 127.0.0.1 ### 執行器IP [選填]:默認為空表示自動獲取IP,多網卡時可手動設置指定IP,該IP不會綁定Host僅作為通訊實用;地址信息用于 "執行器注冊" 和 "調度中心請求并觸發任務";
port: 9999 ### 執行器端口號 [選填]:小于等于0則自動獲取;默認端口為9999,單機部署多個執行器時,注意要配置不同執行器端口;
logpath: /usr/hj/log ### 執行器運行日志文件存儲磁盤路徑 [選填] :需要對該路徑擁有讀寫權限;為空則使用默認路徑;
logretentiondays: 30 ### 執行器日志保存天數 [選填] :值大于3時生效,啟用執行器Log文件定期清理功能,否則不生效;
accessToken:
```
**步驟三:執行器組件配置**執行器組件配置信息位置:/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java找到這個XxlJobConfig.java復制一份到你的項目里
```
package com.hjf.job.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 功能說明:【定時任務:分布式任務調度配置】
* 作 者:lihaijun
* 創建日期:2019-11-09
*/
@Slf4j
@Configuration
public class XxlJobConfig {
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appName;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppName(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 針對多網卡、容器內部署等情況,可借助 "spring-cloud-commons" 提供的 "InetUtils" 組件靈活定制注冊IP;
*
* 1、引入依賴:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器啟動變量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、獲取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
```
\*\*步驟五:執行器項目集群(可選)\*\*執行器支持集群部署,提升調度系統可用性,同時提升任務處理能力。執行器集群部署時,幾點要求和建議:
* 執行器回調地址(xxl.job.admin.addresses)需要保持一致;執行器根據該配置進行執行器自動注冊等操作
* 同一個執行器集群內AppName(xxl.job.executor.appname)需要保持一致;調度中心根據該配置動態發現不同集群的在線執行器列表
## **4.開發自己的任務**
**4.1在執行器項目中新建自己的任務,代碼示例:**
~~~css
/**
* 功能說明:【定時任務:交易統計 每天統計一次】【作廢:啟用延時消息處理】
* 作 者:lihaijun
* 創建日期:2020-01-02
*/
@Transactional
@Slf4j
@Component
@JobHandler(value = "orderPayJob")
public class OrderPayJob extends IJobHandler {
@Resource OrderInfoMapper orderInfoMapper;
@Resource OrderProductMapper orderProductMapper;
@Resource ProductSKUMapper productSKUMapper;
@Override
public ReturnT<String> execute(String param) throws Exception {
try {
log.info("【 訂單庫存處理任務】任務開始執行....");
Query query=new Query();
query.append("createdTime", TimeUtil.getSpecialMinute(-30));
query.append("status", OrderStatus.WaitPay.getValue());
List list = orderInfoMapper.queryList(query);
if (list==null||list.size()<1) {
log.info("【 未支付訂單任務】 沒有檢查到過期訂單");
return SUCCESS;
}
log.info(" 【 訂單庫存處理任務】...結束...");
}catch(Exception e){
log.error("【 訂單庫存處理任務】...異常.." + e.getMessage());
}
return SUCCESS;
}
}
~~~
**4.2在調度中心新建任務**登錄調度中心,點擊下圖所示“新建任務”按鈕,新建示例任務。然后,參考下面截圖中任務的參數配置,點擊保存。

點擊右側啟動此任務,將任務啟動
**4.3啟動調度中心,啟動執行器項目**
*****
*****
\*\*\*\*
- 項目介紹
- 項目聲明
- 項目簡介
- 架構設計
- 項目亮點功能介紹
- 技術棧介紹
- 核心功能
- 運行環境
- 項目更新日志
- 文檔更新日志
- F&Q
- 部署教程
- 環境準備
- JDK安裝
- JDK1.8,17共存
- maven
- 分布式緩存Redis
- 單機版
- 集群
- 注冊&配置中心alibaba/nacos
- 介紹
- Nacos安裝
- Nacos配置中心
- Nacos注冊發現
- Nacos生產部署方案
- 服務監控-BootAdmin
- 基本介紹
- 如何使用
- 整合Admin-Ui
- 客戶端配置
- 鏈路追蹤
- 基本介紹
- SkyWalking-1
- Skywalking-1
- 消息隊列
- Kafka
- docker安裝kafka
- Linux集群
- Maven私服
- nexus安裝部署
- nexus使用介紹
- 全文搜索elasticsearch
- windows集群搭建
- docker安裝es
- ElasticHD
- linux集群部署
- 統一日志解決方案
- 日志解決方案設計
- 介紹與相關資料
- ELK安裝部署
- elasticsearch 7.5
- logstash-7.5
- kibana-7.5
- filebeat
- 服務監控-Prometheus
- Prometheus安裝配置
- Prometheus介紹
- grafana
- 持續集成部署CICD
- 自動化部署Jenkins
- 安裝部署win
- 打包發布遠程執行
- 安裝部署linux
- jenkins+gitlab+docker容器化工程自動化部署
- Git
- CICD說明
- 阿里云效
- CentOS_MYSQL安裝
- docker
- 安裝
- Docker安裝Nginx
- Docker部署啟動springboot
- dockerCompose
- harbor
- Docker私有鏡像倉庫
- Portainer
- Docker遠程連接設置
- 打包工程
- 必要啟動模塊
- 核心模塊
- 登錄認證
- 緩存功能
- 日志模塊
- 分布式鎖
- 消息隊列
- 異常處理
- 系統接口
- 參數驗證
- es檢索
- 數據導出
- 系統設計
- 系統總體架構
- 擴展模塊(可選)
- 限流熔斷alibaba/sentinel
- 使用Sentinel實現gateway網關及服務接口限流
- Sentinel使用Nacos存儲規則及同步
- 服務調用Feign
- Feign基本介紹
- 如何使用
- 負載均衡
- 請求超時
- 請求攔截器
- 分布式任務調度
- XXL-JOB
- 分布式事務
- TX-LCN
- Seata
- Seata原理解析
- 數據庫分庫分表
- swagger文檔
- 分布式ID生成器解決方案
- 服務網關CloudGateway
- 基本介紹
- 使用網關
- 路由配置
- 全局過濾器
- 服務認證授權架構設計
- 認證服務流程
- 授權服務流程
- 系統冪等性設計與實踐
- 分布式日志鏈路跟蹤
- 實時搜索系統設計
- 應用性能
- 壓力測試工具
- Apache JMeter介紹和安裝
- ApacheJMeter使用
- JVM
- JVM性能調優
- 常見JVM內存錯誤及解決方案
- JVM 分析工具詳解
- Spring Cloud性能調優
- Linux運維
- Linux 常用命令
- Linux開啟端口