1. XXL-JOB說明
XXL-JOB是一個分布式任務調度平台,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼並接入多家公司線上產品線,開箱即用。
項目中可能或多或少的會使用到定時調度,如果定時調度任務很多,這時候呢,就可以考慮使用xxl-job 其提供了強大的web管理界面 以及分布式調度特性!
官網文檔地址:https://www.xuxueli.com/xxl-job/
GitHub地址:代碼
Gitee地址:代碼
1.1 XXL-JOB特性
1、簡單:支持通過Web頁面對任務進行CRUD操作,操作簡單,一分鍾上手
2、動態:支持動態修改任務狀態、啟動/停止任務,以及終止運行中任務,即時生效
3、調度中心HA(中心式):調度采用中心式設計,“調度中心”自研調度組件並支持集群部署,可保證調度中心HA
4、執行器HA(分布式):任務分布式執行,任務”執行器”支持集群部署,可保證任務執行HA
5、注冊中心: 執行器會周期性自動注冊任務, 調度中心將會自動發現注冊的任務並觸發執行。同時,也支持手動錄入執行器地址
等等。。。。
1.2 XXL-JOB項目啟動展示(登錄賬號密碼:admin 123456)




2. 創建Maven項目
按下圖步驟,創建一個maven項目。我是創建了一個父子工程,創建了普通的maven項目,在項目下創建不同的springboot項目,也可以直接創建spring boot項目。
2.1 創建項目

2.2 選擇amven項目

2.3 創建xxl-job-admin模塊為調度中心的spring boot項目

2.4 把下載的代碼xxl-job-admin復制過來,目錄結構如下

2.5 創建xxl-job-core核心maven項目

2.6 把下載的代碼xxl-job-core復制過來,目錄結構如下

2.7 創建xxl-job-executor模塊為執行的spring boot項目

2.8 把下載的代碼xxl-job-executor-springboot復制過來,目錄結構如下

2.9 建議直接下載官網代碼或者我的代碼,省去搭建環境的麻煩,官網代碼目錄如下

xxl-job-admin:調度中心
xxl-job-core:公共依賴
xxl-job-executor:執行器Sample示例(選擇合適的版本執行器,可直接使用,也可以參考其並將現有項目改造成執行器)
:xxl-job-excutor-sample-frameless:沒有版本,普通的javaee項目;
:xxl-job-executor-sample-spring:Spring版本,通過Spring容器管理執行器,比較通用,推薦這種方式;
:xxl-job-executor-sample-springboot:Springboot版本,通過Springboot管理執行器;
:xxl-job-executor-sample-jfinal:JFinal版本,通過JFinal管理執行器;
:xxl-job-executor-sample-nutz:Nutz版本,通過Nutz管理執行器;
3. 創建數據庫
3.1 執行數據庫腳本(注意:會直接創建xxl_job的數據庫)
查看代碼
#
# XXL-JOB v2.3.1-SNAPSHOT
# Copyright (c) 2015-present, xuxueli.
CREATE database if NOT EXISTS `xxl_job` default character set utf8mb4 collate utf8mb4_unicode_ci;
use `xxl_job`;
SET NAMES utf8mb4;
CREATE TABLE `xxl_job_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT '執行器主鍵ID',
`job_desc` varchar(255) NOT NULL,
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '報警郵件',
`schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '調度類型',
`schedule_conf` varchar(128) DEFAULT NULL COMMENT '調度配置,值含義取決於調度類型',
`misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '調度過期策略',
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '執行器路由策略',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '執行器任務handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '執行器任務參數',
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞處理策略',
`executor_timeout` int(11) NOT NULL DEFAULT '0' COMMENT '任務執行超時時間,單位秒',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失敗重試次數',
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE類型',
`glue_source` mediumtext COMMENT 'GLUE源代碼',
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE備注',
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新時間',
`child_jobid` varchar(255) DEFAULT NULL COMMENT '子任務ID,多個逗號分隔',
`trigger_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '調度狀態:0-停止,1-運行',
`trigger_last_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '上次調度時間',
`trigger_next_time` bigint(13) NOT NULL DEFAULT '0' COMMENT '下次調度時間',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`job_group` int(11) NOT NULL COMMENT '執行器主鍵ID',
`job_id` int(11) NOT NULL COMMENT '任務,主鍵ID',
`executor_address` varchar(255) DEFAULT NULL COMMENT '執行器地址,本次執行的地址',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '執行器任務handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '執行器任務參數',
`executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '執行器任務分片參數,格式如 1/2',
`executor_fail_retry_count` int(11) NOT NULL DEFAULT '0' COMMENT '失敗重試次數',
`trigger_time` datetime DEFAULT NULL COMMENT '調度-時間',
`trigger_code` int(11) NOT NULL COMMENT '調度-結果',
`trigger_msg` text COMMENT '調度-日志',
`handle_time` datetime DEFAULT NULL COMMENT '執行-時間',
`handle_code` int(11) NOT NULL COMMENT '執行-狀態',
`handle_msg` text COMMENT '執行-日志',
`alarm_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '告警狀態:0-默認、1-無需告警、2-告警成功、3-告警失敗',
PRIMARY KEY (`id`),
KEY `I_trigger_time` (`trigger_time`),
KEY `I_handle_code` (`handle_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_log_report` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`trigger_day` datetime DEFAULT NULL COMMENT '調度-時間',
`running_count` int(11) NOT NULL DEFAULT '0' COMMENT '運行中-日志數量',
`suc_count` int(11) NOT NULL DEFAULT '0' COMMENT '執行成功-日志數量',
`fail_count` int(11) NOT NULL DEFAULT '0' COMMENT '執行失敗-日志數量',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_logglue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`job_id` int(11) NOT NULL COMMENT '任務,主鍵ID',
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE類型',
`glue_source` mediumtext COMMENT 'GLUE源代碼',
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE備注',
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_registry` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`registry_group` varchar(50) NOT NULL,
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_group` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) NOT NULL COMMENT '執行器AppName',
`title` varchar(12) NOT NULL COMMENT '執行器名稱',
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '執行器地址類型:0=自動注冊、1=手動錄入',
`address_list` text COMMENT '執行器地址列表,多地址逗號分隔',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '賬號',
`password` varchar(50) NOT NULL COMMENT '密碼',
`role` tinyint(4) NOT NULL COMMENT '角色:0-普通用戶、1-管理員',
`permission` varchar(255) DEFAULT NULL COMMENT '權限:執行器ID列表,多個逗號分割',
PRIMARY KEY (`id`),
UNIQUE KEY `i_username` (`username`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `xxl_job_lock` (
`lock_name` varchar(50) NOT NULL COMMENT '鎖名稱',
PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `xxl_job_group`(`id`, `app_name`, `title`, `address_type`, `address_list`, `update_time`) VALUES (1, 'xxl-job-executor-sample', '示例執行器', 0, NULL, '2018-11-03 22:21:31' );
INSERT INTO `xxl_job_info`(`id`, `job_group`, `job_desc`, `add_time`, `update_time`, `author`, `alarm_email`, `schedule_type`, `schedule_conf`, `misfire_strategy`, `executor_route_strategy`, `executor_handler`, `executor_param`, `executor_block_strategy`, `executor_timeout`, `executor_fail_retry_count`, `glue_type`, `glue_source`, `glue_remark`, `glue_updatetime`, `child_jobid`) VALUES (1, 1, '測試任務1', '2018-11-03 22:21:31', '2018-11-03 22:21:31', 'XXL', '', 'CRON', '0 0 0 * * ? *', 'DO_NOTHING', 'FIRST', 'demoJobHandler', '', 'SERIAL_EXECUTION', 0, 0, 'BEAN', '', 'GLUE代碼初始化', '2018-11-03 22:21:31', '');
INSERT INTO `xxl_job_user`(`id`, `username`, `password`, `role`, `permission`) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 1, NULL);
INSERT INTO `xxl_job_lock` ( `lock_name`) VALUES ( 'schedule_lock');
commit;
xxl-job.sql
3.2 數據庫表展示

3.3 數據庫表說明
xxl_job_lock:任務調度鎖表;
xxl_job_group:執行器信息表,維護任務執行器信息;
xxl_job_info:調度擴展信息表: 用於保存XXL-JOB調度任務的擴展信息,如任務分組、任務名、機器地址、執行器、執行入參和報警郵件等等;
xxl_job_log:調度日志表: 用於保存XXL-JOB任務調度的歷史信息,如調度結果、執行結果、調度入參、調度機器和執行器等等;
xxl_job_log_report:調度日志報表:用戶存儲XXL-JOB任務調度日志的報表,調度中心報表功能頁面會用到;
xxl_job_logglue:任務GLUE日志:用於保存GLUE更新歷史,用於支持GLUE的版本回溯功能;
xxl_job_registry:執行器注冊表,維護在線的執行器和調度中心機器地址信息;
xxl_job_user:系統用戶表;
4. 修改配置文件
4.1 修改xxl-job-admin配置文件,將其配置成自己需要的調度中心,通過該工程能夠以圖形化的方式統一管理任務調度平台上調度任務,負責觸發調度執行。


可以修改日志文件輸出位置

4.2 修改xxl-job-executor執行器配置文件,修改端口,appName,日志位置

5. 啟動項目調度器和執行器測試
5.1 修改執行器代碼,在控制台打印信息方便測試

5.2 啟動調度器

5.3 啟動執行器


5.4 瀏覽器訪問:http://localhost:8080/xxl-job-admin/

5.5 查看並復制執行器注冊地址

5.6 測試無參的調度器,執行調度任務

6. 自定義調度器和執行器執行調度任務
6.1 創建測試執行器並重啟項目

@XxlJob("testJobHandler")
public void testJobHandler() throws Exception {
String jobParam = XxlJobHelper.getJobParam();
System.out.println("執行成功,參數:" + jobParam);
}
6.2 頁面創建調度器

6.3 創建調度器說明
- 執行器:任務的綁定的執行器,任務觸發調度時將會自動發現注冊成功的執行器, 實現任務自動發現功能; 另一方面也可以方便的進行任務分組。每個任務必須綁定一個執行器, 可在 "執行器管理" 進行設置;
- 任務描述:任務的描述信息,便於任務管理;
- 路由策略:當執行器集群部署時,提供豐富的路由策略,包括;
FIRST(第一個):固定選擇第一個機器;
LAST(最后一個):固定選擇最后一個機器;
ROUND(輪詢):;
RANDOM(隨機):隨機選擇在線的機器;
CONSISTENT_HASH(一致性HASH):每個任務按照Hash算法固定選擇某一台機器,且所有任務均勻散列在不同機器上。
LEAST_FREQUENTLY_USED(最不經常使用):使用頻率最低的機器優先被選舉;
LEAST_RECENTLY_USED(最近最久未使用):最久為使用的機器優先被選舉;
FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定為目標執行器並發起調度;
BUSYOVER(忙碌轉移):按照順序依次進行空閑檢測,第一個空閑檢測成功的機器選定為目標執行器並發起調度;
SHARDING_BROADCAST(分片廣播):廣播觸發對應集群中所有機器執行一次任務,同時系統自動傳遞分片參數;可根據分片參數開發分片任務;
- Cron:觸發任務執行的Cron表達式;
- 運行模式:
BEAN模式:任務以JobHandler方式維護在執行器端;需要結合 "JobHandler" 屬性匹配執行器中任務;
GLUE模式(Java):任務以源碼方式維護在調度中心;該模式的任務實際上是一段繼承自IJobHandler的Java類代碼並 "groovy" 源碼方式維護,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器里中的其他服務;
GLUE模式(Shell):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "shell" 腳本;
GLUE模式(Python):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "python" 腳本;
GLUE模式(PHP):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "php" 腳本;
GLUE模式(NodeJS):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "nodejs" 腳本;
GLUE模式(PowerShell):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "PowerShell" 腳本;
- JobHandler:運行模式為 "BEAN模式" 時生效,對應執行器中新開發的JobHandler類“@JobHandler”注解自定義的value值;
- 阻塞處理策略:調度過於密集執行器來不及處理時的處理策略;
單機串行(默認):調度請求進入單機執行器后,調度請求進入FIFO隊列並以串行方式運行;
丟棄后續調度:調度請求進入單機執行器后,發現執行器存在運行的調度任務,本次請求將會被丟棄並標記為失敗;
覆蓋之前調度:調度請求進入單機執行器后,發現執行器存在運行的調度任務,將會終止運行中的調度任務並清空隊列,然后運行本地調度任務;
- 子任務:每個任務都擁有一個唯一的任務ID(任務ID可以從任務列表獲取),當本任務執行結束並且執行成功時,將會觸發子任務ID所對應的任務的一次主動調度。
- 任務超時時間:支持自定義任務超時時間,任務運行超時將會主動中斷任務;
- 失敗重試次數;支持自定義任務失敗重試次數,當任務失敗時將會按照預設的失敗重試次數主動進行重試;
- 報警郵件:任務調度失敗時郵件通知的郵箱地址,支持配置多郵箱地址,配置多個郵箱地址時用逗號分隔;
- 負責人:任務的負責人;
- 執行參數:任務執行所需的參數,多個參數時用逗號分隔,任務執行時將會把多個參數轉換成數組傳入;
6.4 執行調度器查看結果

6.5 運行報表功能

6.6 調度日志功能

6.7 用戶管理功能

