分佈式任務調度平臺XXL-JOB

原地址:http://www.cnblogs.com/xuxueli/p/5021979.html

                                   《分佈式任務調度平臺XXL-JOB》

一、簡介

1.1 概述

XXL-JOB是一個輕量級分佈式任務調度框架,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。現已開放源代碼並接入多家公司線上產品線,開箱即用。

1.2 特性

  • 1、簡單:支持通過Web頁面對任務進行CRUD操作,操作簡單,一分鐘上手;
  • 2、動態:支持動態修改任務狀態、暫停/恢復任務,以及終止運行中任務,即時生效;
  • 3、調度中心HA(中心式):調度採用中心式設計,“調度中心”基於集羣Quartz實現,可保證調度中心HA;
  • 4、執行器HA(分佈式):任務分佈式執行,任務"執行器"支持集羣部署,可保證任務執行HA;
  • 5、任務Failover:執行器集羣部署時,任務路由策略選擇"故障轉移"情況下調度失敗時將會平滑切換執行器進行Failover;
  • 6、一致性:“調度中心”通過DB鎖保證集羣分佈式調度的一致性, 一次任務調度只會觸發一次執行;
  • 7、自定義任務參數:支持在線配置調度任務入參,即時生效;
  • 8、調度線程池:調度系統多線程觸發調度運行,確保調度精確執行,不被堵塞;
  • 9、彈性擴容縮容:一旦有新執行器機器上線或者下線,下次調度時將會重新分配任務;
  • 10、郵件報警:任務失敗時支持郵件報警,支持配置多郵件地址羣發報警郵件;
  • 11、狀態監控:支持實時監控任務進度;
  • 12、Rolling執行日誌:支持在線查看調度結果,並且支持以Rolling方式實時查看執行器輸出的完整的執行日誌;
  • 13、GLUE:提供Web IDE,支持在線開發任務邏輯代碼,動態發佈,實時編譯生效,省略部署上線的過程。支持30個版本的歷史版本回溯。
  • 14、數據加密:調度中心和執行器之間的通訊進行數據加密,提升調度信息安全性;
  • 15、任務依賴:支持配置子任務依賴,當父任務執行結束且執行成功後將會主動觸發一次子任務的執行, 多個子任務用逗號分隔;
  • 16、推送maven中央倉庫: 將會把最新穩定版推送到maven中央倉庫, 方便用戶接入和使用;
  • 17、任務註冊: 執行器會週期性自動註冊任務, 調度中心將會自動發現註冊的任務並觸發執行。同時,也支持手動錄入執行器地址;
  • 18、路由策略:執行器集羣部署時提供豐富的路由策略,包括:第一個、最後一個、輪詢、隨機、一致性HASH、最不經常使用、最近最久未使用、故障轉移;
  • 19、運行報表:支持實時查看運行數據,如任務數量、調度次數、執行器數量等;以及調度報表,如調度日期分佈圖,調度成功分佈圖等;
  • 20、腳本任務:支持以GLUE模式開發和運行腳本任務,包括Shell、Python等類型腳本;
  • 21、阻塞處理策略:調度過於密集執行器來不及處理時的處理策略,策略包括:單機串行(默認)、丟棄後續調度、覆蓋之前調度;
  • 22、失敗處理策略;調度失敗時的處理策略,策略包括:失敗告警(默認)、失敗重試;

1.3 發展

於2015年中,我在github上創建XXL-JOB項目倉庫並提交第一個commit,隨之進行系統結構設計,UI選型,交互設計……

於2015-11月,XXL-JOB終於RELEASE了第一個大版本V1.0, 隨後我將之發佈到OSCHINA,XXL-JOB在OSCHINA上獲得了@紅薯的熱門推薦,同期分別達到了OSCHINA的“熱門動彈”排行第一和git.oschina的開源軟件月熱度排行第一,在此特別感謝紅薯,感謝大家的關注和支持。

於2015-12月,我將XXL-JOB發表到我司內部知識庫,並且得到內部同事認可。

於2016-01月,我司展開XXL-JOB的內部接入和定製工作,在此感謝袁某和尹某兩位同事的貢獻,同時也感謝內部其他給與關注與支持的同事。

於2017-05-13,在上海舉辦的 "第62期開源中國源創會" 的 "放碼過來" 環節,我登臺對XXL-JOB做了演講,臺下五百位在場觀衆反響熱烈(圖文回顧 )。

我司大衆點評目前已接入XXL-JOB,內部別名《Ferrari》(Ferrari基於XXL-JOB的V1.1版本定製而成,新接入應用推薦升級最新版本)。

據最新統計, 自2016-01-21接入至2017-04-27期間,該系統已調度約45萬餘次,表現優異。新接入應用推薦使用最新版本,因爲經過數個大版本的更新,系統的任務模型、UI交互模型以及底層調度通訊模型都有了較大的優化和提升,核心功能更加穩定高效。

至今,XXL-JOB已接入多家公司的線上產品線,接入場景如電商業務,O2O業務和大數據作業等,截止2016-07-19爲止,XXL-JOB已接入的公司包括不限於:

- 1、大衆點評;
- 2、山東學而網絡科技有限公司;
- 3、安徽慧通互聯科技有限公司;
- 4、人人聚財金服;
- 5、上海棠棣信息科技股份有限公司
- 6、運滿滿
- 7、米其林 (中國區)
- 8、媽媽聯盟
- 9、九櫻天下(北京)信息技術有限公司
- 10、萬普拉斯科技有限公司(一加手機)
- 11、上海億保健康管理有限公司
- 12、海爾馨廚 (海爾)
- 13、河南大紅包電子商務有限公司
- 14、成都順點科技有限公司
- 15、深圳市怡亞通
- 16、深圳麥亞信科技股份有限公司
- 17、上海博瑩科技信息技術有限公司
- 18、中國平安科技有限公司
- 19、杭州知時信息科技有限公司
- 20、博瑩科技(上海)有限公司
- 21、成都依能股份有限責任公司
- 22、湖南高陽通聯信息技術有限公司
- 23、深圳市邦德文化發展有限公司
- 24、福建阿思可網絡教育有限公司
- 25、優信二手車
- 26、上海悠遊堂投資發展股份有限公司
- 27、北京粉筆藍天科技有限公司
- 28、中秀科技(無錫)有限公司
- 29、武漢空心科技有限公司
- 30、北京螞蟻風暴科技有限公司
- 31、四川互宜達科技有限公司
- ……

歡迎大家的關注和使用,XXL-JOB也將擁抱變化,持續發展。

1.4 下載

源碼倉庫地址 (將會在兩個git倉庫同步發佈最新代碼)

源碼倉庫地址 Release Download
https://github.com/xuxueli/xxl-job Download
http://git.oschina.net/xuxueli0323/xxl-job Download

中央倉庫地址 (最新Release版本:1.7.2)

<!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>1.7.2</version>
</dependency>

博客地址 (將會在兩個博客同步更新文檔)

技術交流羣 (僅作技術交流)

  • 羣4:464762661 
  • 羣3:242151780 (羣即將滿,請加羣4)
  • 羣2:438249535 (羣即將滿,請加羣4)
  • 羣1:367260654 (羣即將滿,請加羣4)

1.5 環境

  • JDK:1.7+
  • Servlet/JSP Spec:3.1/2.3
  • Tomcat:8.5.x/Jetty9.2
  • Spring-boot:1.3.8/Spring4.x
  • Mysql:5.6+
  • Maven:3+

二、快速入門

2.1 初始化“調度數據庫”

請下載項目源碼並解壓,獲取 "調度數據庫初始化SQL腳本"(腳本文件爲: 源碼解壓根目錄\xxl-job\db\tables_xxl_job.sql) 並執行即可。正常情況下,應該生成16張表;

調度中心支持集羣部署,集羣情況下各節點務必連接同一個mysql實例;

如果mysql做主從,調度中心集羣節點務必強制走主庫;

2.2 編譯源碼

解壓源碼,按照maven格式將源碼導入IDE, 使用maven進行編譯即可,源碼結構如下圖所示:

xxl-job-admin:調度中心
xxl-job-core:公共依賴
xxl-job-executor-example:執行器Example(可直接使用執行器Example,也可以將現有項目改造成執行器使用)
xxl-job-executor-springboot-example:執行器Example,springboot版本

2.3 配置部署“調度中心”

調度中心項目:xxl-job-admin
作用:統一管理任務調度平臺上調度任務,負責觸發調度執行。

步驟一:調度中心配置:

配置文件以及配置屬性如下圖所示。

### 調度中心JDBC鏈接:鏈接地址請保持和 2.1章節 所創建的調度數據庫的地址一致
xxl.job.db.driverClass=com.mysql.jdbc.Driver
xxl.job.db.url=jdbc:mysql://localhost:3306/xxl-job?useUnicode=true&amp;characterEncoding=UTF-8
xxl.job.db.user=root
xxl.job.db.password=root_pwd

### 報警郵箱
xxl.job.mail.host=smtp.163.com
xxl.job.mail.port=25
[email protected]
xxl.job.mail.password=asdfzxcv
[email protected]
xxl.job.mail.sendNick=《任務調度平臺XXL-JOB》

# 登錄賬號
xxl.job.login.username=admin
xxl.job.login.password=123456

步驟二:部署項目:

如果已經正確進行上述配置,可將項目編譯打war包並部署到tomcat中。 訪問鏈接:http://localhost:8080/xxl-job-admin/,登錄後運行界面如下圖所示

至此“調度中心”項目已經部署成功。

2.4 配置部署“執行器項目”

“執行器”項目:xxl-job-executor-example (如新建執行器項目,可參考該Example執行器項目的配置步驟;)
作用:負責接收“調度中心”的調度並執行;

步驟一:maven依賴

確認pom文件中引入了 "xxl-job-core" 的maven依賴;

步驟二:執行器配置

配置文件以及配置屬性如下圖所示。

### xxl-job admin address list:調度中心部署跟地址:如調度中心集羣部署存在多個地址則用逗號分隔。執行器將會使用該地址進行"執行器心跳註冊"和"任務結果回調"。
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin

### xxl-job executor address:執行器"AppName"和地址信息配置:AppName執行器心跳註冊分組依據;地址信息用於"調度中心請求並觸發任務"和"執行器註冊"。執行器默認端口爲9999,執行器IP默認爲空表示自動獲取IP,多網卡時可手動設置指定IP。單機部署多個執行器時,注意要配置不同執行器端口;
xxl.job.executor.appname=xxl-job-executor-example
xxl.job.executor.ip=
xxl.job.executor.port=9999

### xxl-job log path:執行器運行日誌文件存儲的磁盤位置
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler/

步驟三:執行器組件配置

配置內容如下圖所示。

1、JobHandler 掃描路徑:自動掃描容器中JobHandler;
2、執行器Excutor配置:執行器核心配置;

步驟四:部署項目:

如果已經正確進行上述配置,可將執行器項目編譯打部署,系統提供兩個執行器example項目,選擇其中一個即可,各自的部署方式如下。

xxl-job-executor-example:項目編譯打包成WAR包,並部署到tomcat中。
xxl-job-executor-springboot-example:項目編譯打包成springboot類型的可執行JAR包,命令啓動即可;

至此“執行器”項目已經部署結束。

2.5 開發第一個任務“Hello World”

本示例以新建一個 “GLUE模式(Java)” 運行模式的任務爲例。更多有關任務的詳細配置,請查看“章節三:任務詳解”。 ( “GLUE模式(Java)”的執行代碼託管到調度中心在線維護,相比“Bean模式任務”需要在執行器項目開發部署上線,更加簡便輕量)

前提:請確認“調度中心”和“執行器”項目已經成功部署並啓動;

步驟一:新建任務:

登錄調度中心,點擊下圖所示“新建任務”按鈕,新建示例任務。然後,參考下面截圖中任務的參數配置,點擊保存。

步驟二:“GLUE模式(Java)” 任務開發:

請點擊任務右側 “GLUE” 按鈕,進入 “GLUE編輯器開發界面” ,見下圖。“GLUE模式(Java)” 運行模式的任務默認已經初始化了示例任務代碼,即打印Hello World。 ( “GLUE模式(Java)” 運行模式的任務實際上是一段繼承自IJobHandler的Java類代碼,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器裏中的其他服務,詳細介紹請查看第三章節)

步驟三:觸發執行:

請點擊任務右側 “執行” 按鈕,可手動觸發一次任務執行(通常情況下,通過配置Cron表達式進行任務調度出發)。

步驟四:查看日誌:

請點擊任務右側 “日誌” 按鈕,可前往任務日誌界面查看任務日誌。 在任務日誌界面中,可查看該任務的歷史調度記錄以及每一次調度的任務調度信息、執行參數和執行信息。運行中的任務點擊右側的“執行日誌”按鈕,可進入日誌控制檯查看實時執行日誌。

在日誌控制檯,可以Rolling方式實時查看任務在執行器一側運行輸出的日誌信息,實時監控任務進度;

三、任務詳解

配置屬性詳細說明:

- 執行器:任務的綁定的執行器,任務觸發調度時將會自動發現註冊成功的執行器, 實現任務自動發現功能; 另一方面也可以方便的進行任務分組。每個任務必須綁定一個執行器, 可在 "執行器管理" 進行設置;
- 描述:任務的描述信息,便於任務管理;
- 路由策略:當執行器集羣部署時,執行器路由規則;
    FIRST(第一個):固定選擇第一個執行器;
    LAST(最後一個):固定選擇最後一個執行器;
    ROUND(輪詢):;
    RANDOM(隨機):隨機選擇在線的執行器;
    CONSISTENT_HASH(一致性HASH):分組下機器地址相同,不同JOB均勻散列在不同機器上,保證分組下機器分配JOB平均;且每個JOB固定調度其中一臺機器;
    LEAST_FREQUENTLY_USED(最不經常使用):單個JOB對應的每個執行器,使用頻率最低的優先被選舉;
    LEAST_RECENTLY_USED(最近最久未使用):單個JOB對應的每個執行器,最久爲使用的優先被選舉;
    FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定爲目標執行器併發起調度;
    BUSYOVER(忙碌轉移):按照順序依次進行空閒檢測,第一個空閒檢測成功的機器選定爲目標執行器併發起調度;
- Cron:觸發任務執行的Cron表達式;
- 運行模式:
    BEAN模式:任務以JobHandler方式維護在執行器端;需要結合 "JobHandler" 屬性匹配執行器中任務;
    GLUE模式(Java):任務以源碼方式維護在調度中心;該模式的任務實際上是一段繼承自IJobHandler的Java類代碼並 "groovy" 源碼方式維護,它在執行器項目中運行,可使用@Resource/@Autowire注入執行器裏中的其他服務;
    GLUE模式(Shell):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "shell" 腳本;
    GLUE模式(Python):任務以源碼方式維護在調度中心;該模式的任務實際上是一段 "python" 腳本;
- JobHandler:運行模式爲 "BEAN模式" 時生效,對應執行器中新開發的JobHandler類“@JobHander”註解自定義的value值;
- 子任務Key:每個任務都擁有一個唯一的任務Key(任務Key可以從任務列表獲取),當本任務執行結束並且執行成功時,將會觸發子任務Key所對應的任務的一次主動調度。
- 阻塞處理策略:調度過於密集執行器來不及處理時的處理策略;
    單機串行(默認):調度請求進入單機執行器後,調度請求進入FIFO隊列並以串行方式運行;
    丟棄後續調度:調度請求進入單機執行器後,發現執行器存在運行的調度任務,本次請求將會被丟棄並標記爲失敗;
    覆蓋之前調度:調度請求進入單機執行器後,發現執行器存在運行的調度任務,將會終止運行中的調度任務並清空隊列,然後運行本地調度任務;
- 失敗處理策略;調度失敗時的處理策略;
    失敗告警(默認):調度失敗時,將會觸發失敗報警,如發送報警郵件;
    失敗重試:調度失敗時,將會主動進行一次失敗重試調度,重試調度後仍然失敗將會觸發一失敗告警。注意當任務以failover方式路由時,每次失敗重試將會觸發新一輪路由。
- 執行參數:任務執行所需的參數,多個參數時用逗號分隔,任務執行時將會把多個參數抓換成數組傳入;
- 報警郵件:任務調度失敗時郵件通知的郵箱地址,支持配置多郵箱地址,配置多個郵箱地址時用逗號分隔;
- 負責人:任務的負責人;

3.1 BEAN模式

任務邏輯以JobHandler的形式存在於“執行器”所在項目中,開發流程如下:

步驟一:執行器項目中,開發JobHandler:

- 1、 新建一個繼承com.xxl.job.core.handler.IJobHandler的Java類;
- 2、 該類被Spring容器掃描爲Bean實例,如加“@Service註解”;
- 3、 添加 “@JobHander(value="自定義jobhandler名稱")”註解,註解的value值爲自定義的JobHandler名稱,該名稱對應的是調度中心新建任務的JobHandler屬性的值。
(可參考xxl-job-executor-example項目中的DemoJobHandler,見下圖)

步驟二:調度中心,新建調度任務

參考上文“配置屬性詳細說明”對新建的任務進行參數配置,運行模式選中 "BEAN模式",JobHandler屬性填寫任務註解@JobHander中定義的值;

3.2 GLUE模式(Java)

任務以源碼方式維護在調度中心,支持通過Web IDE在線更新,實時編譯和生效,因此不需要指定JobHandler。開發流程如下:

步驟一:調度中心,新建調度任務:

參考上文“配置屬性詳細說明”對新建的任務進行參數配置,運行模式選中 "GLUE模式(Java)";

步驟二:開發任務代碼:

選中指定任務,點擊該任務右側“GLUE”按鈕,將會前往GLUE任務的Web IDE界面,在該界面支持對任務代碼進行開發(也可以在IDE中開發完成後,複製粘貼到編輯中)。

版本回溯功能(支持30個版本的版本回溯):在GLUE任務的Web IDE界面,選擇右上角下拉框“版本回溯”,會列出該GLUE的更新歷史,選擇相應版本即可顯示該版本代碼,保存後GLUE代碼即回退到對應的歷史版本;

3.3 GLUE模式(Shell)

步驟一:調度中心,新建調度任務

參考上文“配置屬性詳細說明”對新建的任務進行參數配置,運行模式選中 "GLUE模式(Shell)";

步驟二:開發任務代碼:

選中指定任務,點擊該任務右側“GLUE”按鈕,將會前往GLUE任務的Web IDE界面,在該界面支持對任務代碼進行開發(也可以在IDE中開發完成後,複製粘貼到編輯中)。

該模式的任務實際上是一段 "shell" 腳本;

3.4 GLUE模式(Python)

步驟一:調度中心,新建調度任務

參考上文“配置屬性詳細說明”對新建的任務進行參數配置,運行模式選中 "GLUE模式(Python)";

步驟二:開發任務代碼:

選中指定任務,點擊該任務右側“GLUE”按鈕,將會前往GLUE任務的Web IDE界面,在該界面支持對任務代碼進行開發(也可以在IDE中開發完成後,複製粘貼到編輯中)。

該模式的任務實際上是一段 "python" 腳本;

四、任務管理

4.0 配置執行器

點擊進入"執行器管理"界面, 如下圖: 

1、"調度中心OnLine:"右側顯示在線的"調度中心"列表, 任務執行結束後, 將會以failover的模式進行回調調度中心通知執行結果, 避免回調的單點風險;
2、"執行器列表" 中顯示在線的執行器列表, 可通過"OnLine 機器"查看對應執行器的集羣機器。

點擊按鈕 "+新增執行器" 彈框如下圖, 可新增執行器配置: 

執行器屬性說明

AppName: 是每個執行器集羣的唯一標示AppName, 執行器會週期性以AppName爲對象進行自動註冊。可通過該配置自動發現註冊成功的執行器, 供任務調度時使用;
名稱: 執行器的名稱, 因爲AppName限制字母數字等組成,可讀性不強, 名稱爲了提高執行器的可讀性;
排序: 執行器的排序, 系統中需要執行器的地方,如任務新增, 將會按照該排序讀取可用的執行器列表;
註冊方式:調度中心獲取執行器地址的方式;
    自動註冊:執行器自動進行執行器註冊,調度中心通過底層註冊表可以動態發現執行器機器地址;
    手動錄入:人工手動錄入執行器的地址信息,多地址逗號分隔,供調度中心使用;
機器地址:"註冊方式"爲"手動錄入"時有效,支持人工維護執行器的地址信息;

4.1 新建任務

進入任務管理界面,點擊“新增任務”按鈕,在彈出的“新增任務”界面配置任務屬性後保存即可。詳情頁參考章節 "三、任務詳解"。

4.2 編輯任務

進入任務管理界面,選中指定任務。點擊該任務右側“編輯”按鈕,在彈出的“編輯任務”界面更新任務屬性後保存即可,可以修改設置的任務屬性信息:

4.3 編輯GLUE代碼

該操作僅針對GLUE任務。

選中指定任務,點擊該任務右側“GLUE”按鈕,將會前往GLUE任務的Web IDE界面,在該界面支持對任務代碼進行開發。可參考章節 "3.2 GLUE模式(Java)"。

4.4 暫停/恢復任務

可對任務進行“暫停”和“恢復”操作。 需要注意的是,此處的暫停/恢復僅針對任務的後續調度觸發行爲,不會影響到已經觸發的調度任務,如需終止已經觸發的調度任務,可查看“4.8 終止運行中的任務”

4.5 手動觸發一次調度

點擊“執行”按鈕,可手動觸發一次任務調度,不影響原有調度規則。

4.6 查看調度日誌

點擊“日誌”按鈕,可以查看任務歷史調度日誌。在歷史調入日誌界面可查看每次任務調度的調度結果、執行結果等,點擊“執行日誌”按鈕可查看執行器完整日誌。

調度時間:"調度中心"觸發本次調度並向"執行器"發送任務執行信號的時間;
調度結果:"調度中心"觸發本次調度的結果,200表示成功,500或其他表示失敗;
調度備註:"調度中心"觸發本次調度的日誌信息;
執行器地址:本次任務執行的機器地址
運行模式:觸發調度時任務的運行模式,運行模式可參考章節 "三、任務詳解";
任務參數:本地任務執行的入參
執行時間:"執行器"中本次任務執行結束後回調的時間;
執行結果:"執行器"中本次任務執行的結果,200表示成功,500或其他表示失敗;
執行備註:"執行器"中本次任務執行的日誌信息;
操作:
    "執行日誌"按鈕:點擊可查看本地任務執行的詳細日誌信息;詳見“4.7 查看執行日誌”;
    "終止任務"按鈕:點擊可終止本地調度對應執行器上本任務的執行線程,包括未執行的阻塞任務一併被終止;

4.7 查看執行日誌

點擊執行日誌右側的 “執行日誌” 按鈕,可跳轉至執行日誌界面,可以查看業務代碼中打印的完整日誌,如下圖;

4.8 終止運行中的任務

僅針對執行中的任務。 在任務日誌界面,點擊右側的“終止任務”按鈕,將會向本次任務對應的執行器發送任務終止請求,將會終止掉本次任務,同時會清空掉整個任務執行隊列。

任務終止時通過 "interrupt" 執行線程的方式實現, 將會觸發 "InterruptedException" 異常。因此如果JobHandler內部catch到了該異常並消化掉的話, 任務終止功能將不可用。

因此, 如果遇到上述任務終止不可用的情況, 需要在JobHandler中應該針對 "InterruptedException" 異常進行特殊處理 (向上拋出) , 正確邏輯如下:

try{
    // TODO
} catch (Exception e) {
    if (e instanceof InterruptedException) {
        throw e;
    }
    logger.warn("{}", e);
}

而且,在JobHandler中開啓子線程時,子線程也不可catch處理"InterruptedException",應該主動向上拋出。

4.9 刪除執行日誌

在任務日誌界面,選中執行器和任務之後,點擊右側的"刪除"按鈕將會出現"日誌清理"彈框,彈框中支持選擇不同類型的日誌清理策略,選中後點擊"確定"按鈕即可進行日誌清理操作; 

4.10 刪除任務

點擊刪除按鈕,可以刪除對應任務。

五、總體設計

5.1 源碼目錄介紹

- /doc :文檔資料
- /db :“調度數據庫”建表腳本
- /xxl-job-admin :調度中心,項目源碼
- /xxl-job-core :公共Jar依賴
- /xxl-job-executor-example :執行器,Demo項目源碼(大家可以在該項目上進行開發,也可以將現有項目改造生成執行器項目)

5.2 “調度數據庫”配置

XXL-JOB調度模塊基於Quartz集羣實現,其“調度數據庫”是在Quartz的11張集羣mysql表基礎上擴展而成。

XXL-JOB首先定製了Quartz原生表結構前綴(XXL_JOB_QRTZ_)。

然後,在此基礎上新增了幾張張擴展表,如下: - XXL_JOB_QRTZ_TRIGGER_GROUP:執行器信息表,維護任務執行器信息; - XXL_JOB_QRTZ_TRIGGER_REGISTRY:執行器註冊表,維護在線的執行器和調度中心機器地址信息; - XXL_JOB_QRTZ_TRIGGER_INFO:調度擴展信息表: 用於保存XXL-JOB調度任務的擴展信息,如任務分組、任務名、機器地址、執行器、執行入參和報警郵件等等; - XXL_JOB_QRTZ_TRIGGER_LOG:調度日誌表: 用於保存XXL-JOB任務調度的歷史信息,如調度結果、執行結果、調度入參、調度機器和執行器等等; - XXL_JOB_QRTZ_TRIGGER_LOGGLUE:任務GLUE日誌:用於保存GLUE更新歷史,用於支持GLUE的版本回溯功能;

因此,XXL-JOB調度數據庫共計用於16張數據庫表。

5.3 架構設計

5.3.1 設計思想

將調度行爲抽象形成“調度中心”公共平臺,而平臺自身並不承擔業務邏輯,“調度中心”負責發起調度請求。

將任務抽象成分散的JobHandler,交由“執行器”統一管理,“執行器”負責接收調度請求並執行對應的JobHandler中業務邏輯。

因此,“調度”和“任務”兩部分可以相互解耦,提高系統整體穩定性和擴展性;

5.3.2 系統組成
  • 調度模塊(調度中心): 負責管理調度信息,按照調度配置發出調度請求,自身不承擔業務代碼。調度系統與任務解耦,提高了系統可用性和穩定性,同時調度系統性能不再受限於任務模塊; 支持可視化、簡單且動態的維管理調度信息,包括任務新建,更新,刪除,GLUE開發和任務報警等,所有上述操作都會實時生效,同時支持監控調度結果以及執行日誌,支持執行器Failover。
  • 執行模塊(執行器): 負責接收調度請求並執行任務邏輯。任務模塊專注於任務的執行等操作,開發和維護更加簡單和高效; 接收“調度中心”的執行請求、終止請求和日誌請求等。
5.3.3 架構圖

5.4 調度模塊剖析

5.4.1 quartz的不足

Quartz作爲開源作業調度中的佼佼者,是作業調度的首選。但是集羣環境中Quartz採用API的方式對任務進行管理,從而可以避免上述問題,但是同樣存在以下問題: - 問題一:調用API的的方式操作任務,不人性化; - 問題二:需要持久化業務QuartzJobBean到底層數據表中,系統侵入性相當嚴重。 - 問題三:調度邏輯和QuartzJobBean耦合在同一個項目中,這將導致一個問題,在調度任務數量逐漸增多,同時調度任務邏輯逐漸加重的情況加,此時調度系統的性能將大大受限於業務; XXL-JOB彌補了quartz的上述不足之處。

5.4.2 RemoteHttpJobBean

常規Quartz的開發,任務邏輯一般維護在QuartzJobBean中,耦合很嚴重。XXL-JOB中“調度模塊”和“任務模塊”完全解耦,調度模塊中的所有調度任務使用同一個QuartzJobBean,即RemoteHttpJobBean。不同的調度任務將各自參數維護在各自擴展表數據中,當觸發RemoteHttpJobBean執行時,將會解析不同的任務參數發起遠程調用,調用各自的遠程執行器服務。

這種調用模型類似RPC調用,RemoteHttpJobBean提供調用代理的功能,而執行器提供遠程服務的功能。

5.4.3 調度中心HA(集羣)

基於Quartz的集羣方案,數據庫選用Mysql;集羣分佈式併發環境中使用QUARTZ定時任務調度,會在各個節點會上報任務,存到數據庫中,執行時會從數據庫中取出觸發器來執行,如果觸發器的名稱和執行時間相同,則只有一個節點去執行此任務。

# for cluster
org.quartz.jobStore.tablePrefix = XXL_JOB_QRTZ_
org.quartz.scheduler.instanceId: AUTO
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.isClustered: true
org.quartz.jobStore.clusterCheckinInterval: 1000
5.4.4 調度線程池

默認線程池中線程的數量爲10個,避免單線程因阻塞而引起任務調度延遲。

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

XXL-JOB系統中業務邏輯在遠程執行器執行,調度中心每次調度僅僅負責一次調度請求,執行器會將請求存入執行隊列並且立即響應調度中心;相比直接在quartz的QuartzJobBean中執行業務邏輯,差別就像大象和羽毛;

XXL-JOB調度中心中每個JOB邏輯非常 “輕”,單個JOB一次運行平均耗時基本在 "100ms" 之內(基本是網絡開銷);因此,可以保證使用有限的線程支撐大量的JOB併發運行;上面配置的10個線程至少可以支撐100個JOB正常運行;

5.4.5 @DisallowConcurrentExecution

XXL-JOB調度模塊的“調度中心”默認不使用該註解,即默認開啓並行機制,因爲RemoteHttpJobBean爲公共QuartzJobBean,這樣在多線程調度的情況下,調度模塊被阻塞的機率很低,大大提高了調度系統的承載量。

XXL-JOB的每個調度任務雖然在調度模塊是並行調度執行的,但是任務調度傳遞到任務模塊的“執行器”確實串行執行的,同時支持任務終止。

5.4.6 misfire

錯過了觸發時間,處理規則。 可能原因:服務重啓;調度線程被QuartzJobBean阻塞,線程被耗盡;某個任務啓用了@DisallowConcurrentExecution,上次調度持續阻塞,下次調度被錯過;

quartz.properties中關於misfire的閥值配置如下,單位毫秒:

org.quartz.jobStore.misfireThreshold: 60000

Misfire規則: withMisfireHandlingInstructionDoNothing:不觸發立即執行,等待下次調度; withMisfireHandlingInstructionIgnoreMisfires:以錯過的第一個頻率時間立刻開始執行; withMisfireHandlingInstructionFireAndProceed:以當前時間爲觸發頻率立刻觸發一次執行;

XXL-JOB默認misfire規則爲:withMisfireHandlingInstructionDoNothing

CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfo.getJobCron()).withMisfireHandlingInstructionDoNothing();
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
5.4.7 日誌回調服務

調度模塊的“調度中心”作爲Web服務部署時,一方面承擔調度中心功能,另一方面頁爲執行器提供API服務。

調度中心提供的"日誌回調服務API服務"代碼位置如下:

xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback

“執行器”在接收到任務執行請求後,執行任務,在執行結束之後會將執行結果回調通知“調度中心”,代碼位置爲:

5.4.8 任務HA(Failover)

執行器如若集羣部署,調度中心將會感知到在線的所有執行器,如“127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999”。

當任務"路由策略"選擇"故障轉移(FAILOVER)"時,當調度中心每次發起調度請求時,會按照順序對執行器發出心跳檢測請求,第一個檢測爲存活狀態的執行器將會被選定併發送調度請求。 

調度成功後,可在日誌監控界面查看“調度備註”,如下; 

“調度備註”可以看出本地調度運行軌跡,執行器的"註冊方式"、"地址列表"和任務的"路由策略"。"故障轉移(FAILOVER)"路由策略下,調度中心首先對第一個地址進行心跳檢測,心跳失敗因此自動跳過,第二個依然心跳檢測失敗…… 直至心跳檢測第三個地址“127.0.0.1:9999”成功,選定爲“目標執行器”;然後對“目標執行器”發送調度請求,調度流程結束,等待執行器回調執行結果。

5.4.9 調度日誌

調度中心每次進行任務調度,都會記錄一條任務日誌,任務日誌主要包括以下三部分內容:

  • 任務信息:包括“執行器地址”、“JobHandler”和“執行參數”等屬性,根據這些參數,可以精確的定位任務執行的具體機器和任務代碼;
  • 調度信息:包括“調度時間”、“調度結果”和“調度日誌”等,根據這些參數,可以瞭解“調度中心”發起調度請求時具體情況。
  • 執行信息:包括“執行時間”、“執行結果”和“執行日誌”等,根據這些參數,可以瞭解在“執行器”端任務執行的具體情況;

調度日誌,針對單次調度,屬性說明如下:

  • 執行器地址:任務執行的機器地址;
  • JobHandler:Bean模式表示任務執行的JobHandler名稱;
  • 任務參數:任務執行的入參;
  • 調度時間:調度中心,發起調度的時間;
  • 調度結果:調度中心,發起調度的結果,SUCCESS或FAIL;
  • 調度備註:調度中心,發起調度的備註信息,如地址心跳檢測日誌等;
  • 執行時間:執行器,任務執行結束後回調的時間;
  • 執行結果:執行器,任務執行的結果,SUCCESS或FAIL;
  • 執行備註:執行器,任務執行的備註信息,如異常日誌等;
  • 執行日誌:任務執行過程中,業務代碼中打印的完整執行日誌,見“4.7 查看執行日誌”;
5.4.10 任務依賴

原理:XXL-JOB中每個任務都對應有一個任務Key,同時,每個任務支持設置屬性“子任務Key”,因此,通過“任務Key”可以匹配任務依賴關係。

當父任務執行結束並且執行成功時,將會根據“子任務Key”匹配子任務依賴,如果匹配到子任務,將會主動觸發一次子任務的執行。

在任務日誌界面,點擊任務的“執行備註”的“查看”按鈕,可以看到匹配子任務以及觸發子任務執行的日誌信息,如無信息則表示未觸發子任務執行,可參考下圖。

5.5 任務 "運行模式" 剖析

5.5.1 "Bean模式" 任務

開發步驟:可參考 "章節三" ; 原理:每個Bean模式任務都是一個Spring的Bean類實例,它被維護在“執行器”項目的Spring容器中。任務類需要加“@JobHander(value="名稱")”註解,因爲“執行器”會根據該註解識別Spring容器中的任務。任務類需要繼承統一接口“IJobHandler”,任務邏輯在execute方法中開發,因爲“執行器”在接收到調度中心的調度請求時,將會調用“IJobHandler”的execute方法,執行任務邏輯。

5.5.2 "GLUE模式(Java)" 任務

開發步驟:可參考 "章節三" ; 原理:每個 "GLUE模式(Java)" 任務的代碼,實際上是“一個繼承自“IJobHandler”的實現類的類代碼”,“執行器”接收到“調度中心”的調度請求時,會通過Groovy類加載器加載此代碼,實例化成Java對象,同時注入此代碼中聲明的Spring服務(請確保Glue代碼中的服務和類引用在“執行器”項目中存在),然後調用該對象的execute方法,執行任務邏輯。

5.5.3 GLUE模式(Shell) + GLUE模式(Python)

開發步驟:可參考 "章節三" ; 原理:腳本任務的源碼託管在調度中心,腳本邏輯在執行器運行。當觸發腳本任務時,執行器會加載腳本源碼在執行器機器上生成一份腳本文件,然後通過Java代碼調用該腳本;並且實時將腳本輸出日誌寫到任務日誌文件中,從而在調度中心可以實時監控腳本運行情況;腳本返回碼爲0時表示執行成功,其他標示執行失敗。

目前支持的腳本類型如下:

- shell腳本:任務運行模式選擇爲 "GLUE模式(Shell)"時支持 "shell" 腳本任務;
- python腳本:任務運行模式選擇爲 "GLUE模式(Python)"時支持 "python" 腳本任務;
5.5.4 執行器

執行器實際上是一個內嵌的Jetty服務器,默認端口9999,如下圖配置文件所示(參數:xxl.job.executor.port)。

在項目啓動時,執行器會通過“@JobHander”識別Spring容器中“Bean模式任務”,以註解的value屬性爲key管理起來。

“執行器”接收到“調度中心”的調度請求時,如果任務類型爲“Bean模式”,將會匹配Spring容器中的“Bean模式任務”,然後調用其execute方法,執行任務邏輯。如果任務類型爲“GLUE模式”,將會加載GLue代碼,實例化Java對象,注入依賴的Spring服務(注意:Glue代碼中注入的Spring服務,必須存在與該“執行器”項目的Spring容器中),然後調用execute方法,執行任務邏輯。

5.5.5 任務日誌

XXL-JOB會爲每次調度請求生成一個單獨的日誌文件,需要通過 "XxlJobLogger.log" 打印執行日誌,“調度中心”查看執行日誌時將會加載對應的日誌文件。

(歷史版本通過重寫LOG4J的Appender實現,存在依賴限制,該方式在新版本已經被拋棄)

日誌文件存放的位置可在“執行器”配置文件進行自定義,默認目錄格式爲:/data/applogs/xxl-job/jobhandler/“格式化日期”/“數據庫調度日誌記錄的主鍵ID.log”。

在JobHandler中開啓子線程時,子線程將會將會把日誌打印在父線程即JobHandler的執行日誌中,方便日誌追蹤。

5.6 通訊模塊剖析

5.6.1 一次完整的任務調度通訊流程
- 1、“調度中心”向“執行器”發送http調度請求: “執行器”中接收請求的服務,實際上是一臺內嵌jetty服務器,默認端口9999;
- 2、“執行器”執行任務邏輯;
- 3、“執行器”http回調“調度中心”調度結果: “調度中心”中接收回調的服務,是針對執行器開放一套API服務;
5.6.2 通訊數據加密

調度中心向執行器發送的調度請求時使用RequestModel和ResponseModel兩個對象封裝調度請求參數和響應數據, 在進行通訊之前底層會將上述兩個對象對象序列化,並進行數據協議以及時間戳檢驗,從而達到數據加密的功能;

5.7 任務註冊, 任務自動發現

自v1.5版本之後, 任務取消了"任務執行機器"屬性, 改爲通過任務註冊和自動發現的方式, 動態獲取遠程執行器地址並執行。

AppName: 每個執行器機器集羣的唯一標示, 任務註冊以 "執行器" 爲最小粒度進行註冊; 每個任務通過其綁定的執行器可感知對應的執行器機器列表;
Beat: 任務註冊心跳週期, 默認15s; 執行器以一倍Beat進行執行器註冊, 調度中心以一倍Beat進行動態任務發現; 註冊信息的失效時間被兩倍Beat; 
註冊表: 見"XXL_JOB_QRTZ_TRIGGER_REGISTRY"表, "執行器" 在進行任務註冊時將會週期性維護一條註冊記錄,即機器地址和AppName的綁定關係; "調度中心" 從而可以動態感知每個AppName在線的機器列表;

爲保證系統"輕量級"並且降低學習部署成本,沒有采用Zookeeper作爲註冊中心,採用DB方式進行任務註冊發現;

5.8 路由策略

執行器集羣部署時提供豐富的路由策略,包括:

FIRST(第一個):固定選擇第一個執行器;
LAST(最後一個):固定選擇最後一個執行器;
ROUND(輪詢):;
RANDOM(隨機):隨機選擇在線的執行器;
CONSISTENT_HASH(一致性HASH):分組下機器地址相同,不同JOB均勻散列在不同機器上,保證分組下機器分配JOB平均;且每個JOB固定調度其中一臺機器;
LEAST_FREQUENTLY_USED(最不經常使用):單個JOB對應的每個執行器,使用頻率最低的優先被選舉;
LEAST_RECENTLY_USED(最近最久未使用):單個JOB對應的每個執行器,最久爲使用的優先被選舉;
FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定爲目標執行器併發起調度;
BUSYOVER(忙碌轉移):按照順序依次進行空閒檢測,第一個空閒檢測成功的機器選定爲目標執行器併發起調度;

5.9 任務執行結果

自v1.6.2之後,任務執行結果通過 "IJobHandler" 的返回值 "ReturnT" 進行判斷; 當返回值符合 "ReturnT.code == ReturnT.SUCCESS_CODE" 時表示任務執行成功,否則表示任務執行失敗,而且可以通過 "ReturnT.msg" 回調錯誤信息給調度中心; 從而,在任務邏輯中可以方便的控制任務執行結果;

六、版本更新日誌

6.1 版本 V1.1.x,新特性[2015-12-05]

【於V1.1.x版本,XXL-JOB正式應用於我司,內部定製別名爲 “Ferrari”,新接入應用推薦使用最新版本】

  • 1、簡單:支持通過Web頁面對任務進行CRUD操作,操作簡單,一分鐘上手;
  • 2、動態:支持動態修改任務狀態,動態暫停/恢復任務,即時生效;
  • 3、服務HA:任務信息持久化到mysql中,Job服務天然支持集羣,保證服務HA;
  • 4、任務HA:某臺Job服務掛掉,任務會平滑分配給其他的某一臺存活服務,即使所有服務掛掉,重啓時或補償執行丟失任務;
  • 5、一個任務只會在其中一臺服務器上執行;
  • 6、任務串行執行;
  • 7、支持自定義參數;
  • 8、支持遠程任務執行終止;

6.2 版本 V1.2.x,新特性[2016-01-17]

  • 1、支持任務分組;

  • 2、支持“本地任務”、“遠程任務”;

  • 3、底層通訊支持兩種方式,Servlet方式 + JETTY方式;

  • 4、支持“任務日誌”;

  • 5、支持“串行執行”,並行執行;

    說明:V1.2版本將系統架構按功能拆分爲:

      - 調度模塊(調度中心):負責管理調度信息,按照調度配置發出調度請求;
      - 執行模塊(執行器):負責接收調度請求並執行任務邏輯;
      - 通訊模塊:負責調度模塊和任務模塊之間的信息通訊;
    

    優點:

      - 解耦:任務模塊提供任務接口,調度模塊維護調度信息,業務相互獨立;
      - 高擴展性;
      - 穩定性;
    

6.3 版本 V1.3.0,新特性[2016-05-19]

  • 1、遺棄“本地任務”模式,推薦使用“遠程任務”,易於系統解耦,任務對應的JobHander統稱爲“執行器”;

  • 2、遺棄“servlet”方式底層系統通訊,推薦使用JETTY方式,調度+回調雙向通訊,重構通訊邏輯;

  • 3、UI交互優化:左側菜單展開狀態優化,菜單項選中狀態優化,任務列表打開表格有壓縮優化;

  • 4、【重要】“執行器”細分爲:BEAN、GLUE兩種開發模式,簡介見下文:

    “執行器” 模式簡介: - BEAN模式執行器:每個執行器都是Spring的一個Bean實例,XXL-JOB通過註解@JobHander識別和調度執行器; -GLUE模式執行器:每個執行器對應一段代碼,在線Web編輯和維護,動態編譯生效,執行器負責加載GLUE代碼和執行;

6.4 版本 V1.3.1,新特性[2016-05-23]

  • 1、更新項目目錄結構:
    • /xxl-job-admin -------------------- 【調度中心】:負責管理調度信息,按照調度配置發出調度請求;
    • /xxl-job-core ----------------------- 公共依賴
    • /xxl-job-executor-example ------ 【執行器】:負責接收調度請求並執行任務邏輯;
    • /db ---------------------------------- 建表腳本
    • /doc --------------------------------- 用戶手冊
  • 2、在新的目錄結構上,升級了用戶手冊;
  • 3、優化了一些交互和UI;

6.5 版本 V1.3.2,新特性[2016-05-28]

  • 1、調度邏輯進行事務包裹;
  • 2、執行器異步回調執行日誌;
  • 3、【重要】在 “調度中心” 支持HA的基礎上,擴展執行器的Failover支持,支持配置多執行期地址;

6.6 版本 V1.4.0 新特性[2016-07-24]

  • 1、任務依賴: 通過事件觸發方式實現, 任務執行成功並回調時會主動觸發一次子任務的調度, 多個子任務用逗號分隔;
  • 2、執行器底層實現代碼進行重度重構, 優化底層建表腳本;
  • 3、執行器中任務線程分組邏輯優化: 之前根據執行器JobHandler進行線程分組,當多個任務複用Jobhanlder會導致相互阻塞。現改爲根據調度中心任務進行任務線程分組,任務與任務執行相互隔離;
  • 4、執行器調度通訊方案優化, 通過Hex + HC實現建議RPC通訊協議, 優化了通訊參數的維護和解析流程;
  • 5、調度中心, 新建/編輯任務, 界面屬性調整:
    • 5.1、任務新增/編輯界面中去除 "任務名JobName"屬性 ,該屬性改爲系統自動生成: 該字段之前主要用於在 "調度中心" 唯一標示一個任務, 現實意義不大, 因此計劃淡化掉該字段,改爲系統生成UUID,從而簡化任務新建的操作;
    • 5.2、任務新增/編輯界面中去除 "GLUE模式" 複選框位置調整, 改爲貼近"JobHandler"輸入框右側;
    • 5.3、任務新增/編輯界面中去除 "報警閾值" 屬性;
    • 5.4、任務新增/編輯界面中去除 "子任務Key" 屬性, 每個任務全局任務Key可以從任務列表獲取, 當本任務執行結束且成功後, 將會根據子任務Key匹配子任務並主動觸發一次子任務執行;
  • 6、問題修復:
    • 6.1、執行器jetty關閉優化,解決一處可能導致jetty無法關閉的問題;
    • 6.2、執行器任務終止時,執行隊列回調優化,解決一處導致任務無法回調的問題;
    • 6.3、調度中心中列表分頁參數優化,解決一處因服務器限制post長度而引起的問題;
    • 6.4、執行器Jobhandler註解優化,解決一處因事務代理導致的容器無法加載JobHandler的問題;
    • 6.5、遠程調度優化,禁用retry策略,解決一處可能導致重複調用的問題;

Tips: 歷史版本(V1.3.x)目前已經Release至穩定版本, 進入維護階段, 地址見分支 V1.3 。新特性將會在master分支持續更新。

6.7 版本 V1.4.1 新特性[2016-09-06]

  • 1、項目成功推送maven中央倉庫, 中央倉庫地址以及依賴如下:
    <!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
    <dependency>
        <groupId>com.xuxueli</groupId>
        <artifactId>xxl-job-core</artifactId>
        <version>${最新穩定版}</version>
    </dependency>
    
  • 2、爲適配中央倉庫規則, 項目groupId從com.xxl改爲com.xuxueli。
  • 3、系統版本不在維護在項目跟pom中,各個子模塊單獨配置版本配置,解決子模塊無法單獨編譯的問題;
  • 4、底層RPC通訊,傳輸數據的字節長度統計規則優化,可節省50%數據傳輸量;
  • 5、IJobHandler取消任務返回值,原通過返回值判斷執行狀態,邏輯改爲:默認任務執行成功,僅在捕獲異常時認定任務執行失敗。
  • 6、系統公共彈框功能,插件化;
  • 7、底層表結構,表明統一大寫;
  • 8、調度中心,異常處理器JSON響應的ContentType修改,修復瀏覽器不識別的問題;

6.8 版本 V1.4.2 新特性[2016-09-29]

  • 1、推送新版本 V1.4.2 至中央倉庫, 大版本 V1.4 進入維護階段;
  • 2、任務新增時,任務列表偏移問題修復;
  • 3、修復一處因bootstrap不支持模態框重疊而導致的樣式錯亂的問題, 在任務編輯時會出現該問題;
  • 4、調度超時和Handler匹配不到時,調度狀態優化;
  • 5、因catch異常,導致任務不可終止的問題,給出解決方案, 見文檔;

6.9 版本 V1.5.0 特性[2016-11-13]

  • 1、任務註冊: 執行器會週期性自動註冊任務, 調度中心將會自動發現註冊的任務並觸發執行。
  • 2、"執行器" 新增參數 "AppName" : 是每個執行器集羣的唯一標示AppName, 並週期性以AppName爲對象進行自動註冊。
  • 3、調度中心新增欄目 "執行器管理" : 管理在線的執行器, 通過屬性AppName自動發現註冊的執行器。只有被管理的執行器才允許被使用;
  • 4、"任務組"屬性改爲"執行器": 每個任務需要綁定指定的執行器, 調度地址通過綁定的執行器獲取;
  • 5、拋棄"任務機器"屬性: 通過任務綁定的執行器, 自動發現註冊的遠程執行器地址並觸發調度請求。
  • 6、"公共依賴"中新增DBGlueLoader,基於原生jdbc實現GLUE源碼的加載器,減少第三方依賴(mybatis,spring-orm等);精簡和優化執行器測配置(針對GLUE任務),降低上手難度;
  • 7、表結構調整,底層重構優化;
  • 8、"調度中心"自動註冊和發現,failover: 調度中心週期性自動註冊, 任務回調時可以感知在線的所有調度中心地址, 通過failover的方式進行任務回調,避免回調單點風險。

6.10 版本 V1.5.1 特性[2016-11-13]

  • 1、底層代碼重構和邏輯優化,POM清理以及CleanCode;
  • 2、Servlet/JSP Spec設定爲3.0/2.2
  • 3、Spring升級至3.2.17.RELEASE版本;
  • 4、Jetty升級版本至8.2.0.v20160908;
  • 5、已推送V1.5.0和V1.5.1至Maven中央倉庫;

6.10 版本 V1.5.2 特性[2017-02-28]

  • 1、IP工具類獲取IP邏輯優化,IP靜態緩存;
  • 2、執行器、調度中心,均支持自定義註冊IP地址;解決機器多網卡時錯誤網卡註冊的情況;
  • 3、任務跨天執行時生成多份日誌文件的問題修復;
  • 4、底層日誌底層日誌調整,非敏感日誌level調整爲debug;
  • 5、升級數據庫連接池c3p0版本;
  • 6、執行器log4j配置優化,去除無效屬性;
  • 7、底層代碼重構和邏輯優化以及CleanCode;
  • 8、GLUE依賴注入邏輯優化,支持別名注入;

6.11 版本 V1.6.0 特性[2017-03-13]

  • 1、通訊方案升級,原基於HEX的通訊模型調整爲基於HTTP的B-RPC的通訊模型;
  • 2、執行器支持手動設置執行地址列表,提供開關切換使用註冊地址還是手動設置的地址;
  • 3、執行器路由規則:第一個、最後一個、輪詢、隨機、一致性HASH、最不經常使用、最近最久未使用、故障轉移;
  • 4、規範線程模型統一,統一線程銷燬方案(通過listener或stop方法,容器銷燬時銷燬線程;Daemon方式有時不太理想);
  • 5、規範系統配置數據,通過配置文件統一管理;
  • 6、CleanCode,清理無效的歷史參數;
  • 7、底層擴展數據結構以及相關表結構調整;
  • 8、新建任務默認爲非運行狀態;
  • 9、GLUE模式任務實例更新邏輯優化,原根據超時時間更新改爲根據版本號更新,源碼變動版本號加一;

6.12 版本 V1.6.1 特性[2017-03-25]

  • 1、Rolling日誌;
  • 2、WebIDE交互重構;
  • 3、通訊增強校驗,有效過濾非正常請求;
  • 4、權限增強校驗,採用動態登錄TOKEN(推薦接入內部SSO);
  • 5、數據庫配置優化,解決亂碼問題;

6.13 版本 V1.6.2 特性[2017-04-25]

  • 1、運行報表:支持實時查看運行數據,如任務數量、調度次數、執行器數量等;以及調度報表,如調度日期分佈圖,調度成功分佈圖等;
  • 2、JobHandler支持設置任務返回值,在任務邏輯中可以方便的控制任務執行結果;
  • 3、資源路徑包含空格或中文時資源文件無法加載時,無法準確查看異常信息的問題處理。
  • 4、路由策越優化:循環和LFU路由策略計數器自增無上限問題和首次路由壓力集中在首臺機器的問題修復;

6.14 版本 V1.7.0 特性[2017-05-02]

  • 1、腳本任務:支持以GLUE模式開發和運行腳本任務,包括Shell、Python和Groovy等類型腳本;
  • 2、新增spring-boot類型執行器example項目;
  • 3、升級jetty版本至9.2;
  • 4、任務運行日誌移除log4j組件依賴,改爲底層自主實現,從而取消了對日誌組件的依賴限制;
  • 5、執行器移除GlueLoader依賴,改爲推送方式實現,從而GLUE源碼加載不再依賴JDBC;
  • 6、登錄攔截Redirect時獲取項目名,解決非根據目錄發佈時跳轉404問題;

6.15 版本 V1.7.1 特性[2017-05-08]

  • 1、運行日誌讀寫編碼統一爲UTF-8,解決windows環境下日誌亂碼問題;
  • 2、通訊超時時間限定爲10s,避免異常情況下調度線程佔用;
  • 3、執行器,server啓動、銷燬和註冊邏輯調整;
  • 4、JettyServer關閉邏輯優化,修復執行器無法正常關閉導致端口占用和頻繁打印c3p0日誌的問題;
  • 5、JobHandler中開啓子線程時,支持子線程輸出執行日誌並通過Rolling查看。
  • 6、任務日誌清理功能;
  • 7、彈框組件統一替換爲layer;
  • 8、升級quartz版本至2.3.0;

6.15 版本 V1.7.2 特性[2017-05-17]

  • 1、阻塞處理策略:調度過於密集執行器來不及處理時的處理策略,策略包括:單機串行(默認)、丟棄後續調度、覆蓋之前調度;
  • 2、失敗處理策略;調度失敗時的處理策略,策略包括:失敗告警(默認)、失敗重試;
  • 3、通訊時間戳超時時間調整爲180s;
  • 4、執行器與數據庫徹底解耦,但是執行器需要配置調度中心集羣地址。調度中心提供API供執行器回調和心跳註冊服務,取消調度中心內部jetty,心跳週期調整爲30s,心跳失效爲三倍心跳;
  • 5、執行參數編輯時丟失問題修復;
  • 6、新增任務測試Demo,方便在開發時進行任務邏輯測試;

6.16 版本 V1.8.0 特性[Coding]

  • 1、任務Cron更新邏輯優化,改爲rescheduleJob,同時防止cron重複設置;
  • 2、優化:API回調服務失敗狀態碼優化,方便問題排查;
  • 3、XxlJobLogger的日誌多參數支持;
  • 4、路由策略新增 "忙碌轉移" 模式:按照順序依次進行空閒檢測,第一個空閒檢測成功的機器選定爲目標執行器併發起調度;
  • 5、路由策略代碼重構;
  • 6、執行器重複註冊問題修復;
  • 7、任務線程輪空30次後自動銷燬,降低低頻任務的無效線程消耗。
  • 8、執行器任務執行結果批量回調,降低迴調頻率提升執行器性能;
  • 9、springboot版本執行器,取消XML配置,改爲類配置方式;

TODO LIST

  • 1、任務權限管理:執行器爲粒度分配權限,核心操作校驗權限;
  • 2、任務分片:一個任務被拆分成N個獨立的任務單元,然後由分佈式部署的執行器分別執行某一個或幾個分片單元;
  • 3、任務分片路由:分片採用一致性Hash算法計算出儘量穩定的分片順序,即使註冊機器存在波動也不會引起分批分片順序大的波動;
  • 4、失敗重試優化:目前失敗重試邏輯爲,在本次調度請求失敗後重新執行一次請求邏輯。優化點爲針對調度和執行失敗時均做失敗重試,重試時重新觸發一次完整調度,這將可能導致失敗是調度死循環,考慮中。
  • 5、回調失敗寫文件,查看日誌時讀文件確認,重啓後回調確認;
  • 6、任務依賴,流程圖,子任務+會籤任務,各節點日誌;
  • 7、調度任務優先級;
  • 8、移除quartz依賴,重寫調度模塊:新增或恢復任務時將下次執行記錄插入delayqueue,調度中心集羣競爭分佈式鎖,成功節點批量加載到期delayqueue數據,批量執行。
  • 9、任務執行結果回調失敗後重試:待定,防止回調死循環;
發佈了31 篇原創文章 · 獲贊 11 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章