本文主要介紹分佈式任務調度平臺XXL-JOB(v2.1.0版本),包括功能特性、實現原理、優缺點、同類框架比較等mysql
項目開發中,經常如下場景須要分佈式任務調度:git
所以,XXL-JOB應運而生: XXL-JOB是一個開源的輕量級分佈式任務調度平臺,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展、開箱即用,其中「XXL」是主要做者,大衆點評許雪裏名字的縮寫github
自2015年開源以來,已接入數百家公司的線上產品線,接入場景涉及電商業務,O2O業務和大數據做業等spring
主要功能特性以下:sql
簡單靈活 提供Web頁面對任務進行管理,管理系統支持用戶管理、權限控制; 支持容器部署; 支持經過通用HTTP提供跨平臺任務調度;數據庫
豐富的任務管理功能 支持頁面對任務CRUD操做; 支持在頁面編寫腳本任務、命令行任務、Java代碼任務並執行; 支持任務級聯編排,父任務執行結束後觸發子任務執行; 支持設置任務優先級; 支持設置指定任務執行節點路由策略,包括輪詢、隨機、廣播、故障轉移、忙碌轉移等; 支持Cron方式、任務依賴、調度中心API接口方式觸發任務執行bash
高性能 調度中心基於線程池多線程觸發調度任務,快任務、慢任務基於線程池隔離調度,提供系統性能和穩定性; 任務調度流程全異步化設計實現,如異步調度、異步運行、異步回調等,有效對密集調度進行流量削峯;服務器
高可用 任務調度中心、任務執行節點均 集羣部署,支持動態擴展、故障轉移 支持任務配置路由故障轉移策略,執行器節點不可用是自動轉移到其餘節點執行 支持任務超時控制、失敗重試配置 支持任務處理阻塞策略:調度當任務執行節點忙碌時來不及執行任務的處理策略,包括:串行、拋棄、覆蓋策略網絡
易於監控運維 支持設置任務失敗郵件告警,預留接口支持短信、釘釘告警; 支持實時查看任務執行運行數據統計圖表、任務進度監控數據、任務完整執行日誌;多線程
將調度行爲抽象造成「調度中心」公共平臺,而平臺自身並不承擔業務邏輯,「調度中心」負責發起調度請求; 將任務抽象成分散的JobHandler,交由「執行器」統一管理,「執行器」負責接收調度請求並執行對應的JobHandler中業務邏輯; 所以,「調度」和「任務」兩部分能夠相互解耦,提升系統總體穩定性和擴展性;
調度模塊(調度中心): 負責管理調度信息,按照調度配置發出調度請求,自身不承擔業務代碼。調度系統與任務解耦,提升了系統可用性和穩定性,同時調度系統性能再也不受限於任務模塊; 支持可視化、簡單且動態的管理調度信息,包括任務新建,更新,刪除,任務報警等,全部上述操做都會實時生效,同時支持監控調度結果以及執行日誌,支持執行器Failover
執行模塊(執行器): 負責接收調度請求並執行任務邏輯。任務模塊專一於任務的執行等操做,開發和維護更加簡單和高效; 接收「調度中心」的執行請求、終止請求和日誌請求等
調度中心支持多節點部署,基於數據庫行鎖保證同時只有一個調度中心節點觸發任務調度,參考com.xxl.job.admin.core.thread.JobScheduleHelper#start
Connection conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();
connAutoCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );
preparedStatement.execute();
# 觸發任務調度
# 事務提交
conn.commit();
複製代碼
路由策略 調度中心基於路由策略路由選擇一個執行器節點執行任務,XXL-JOB提供了以下路由策略保證任務調度高可用: 忙碌轉移策略: 下發任務前向執行器節點發起rpc心跳請求查詢是否忙碌,若是執行器節點返回忙碌則轉移到其餘執行器節點執行(參考 com.xxl.job.admin.core.route.strategy.ExecutorRouteBusyover) 故障轉移策略: 下發任務前向執行器節點發起rpc心跳請求查詢是否在線,若是執行器節點沒返回或者返回不可用則轉移到其餘執行器節點執行 (參考com.xxl.job.admin.core.route.strategy.ExecutorRouteFailover)
阻塞處理策略 當執行器節點存在多個相同任務id的任務未執行完成,則須要基於阻塞策略對任務進行取捨: 串行策略:默認策略,任務進行排隊、丟棄舊任務策略、丟棄新任務策略 (參考:com.xxl.job.core.biz.impl.ExecutorBizImpl#run)
特性 | quartz | elastic-job-lite | xxl-job | LTS |
---|---|---|---|---|
依賴 | MySQL、jdk | jdk、zookeeper | mysql、jdk | jdk、zookeeper、maven |
高可用 | 多節點部署,經過競爭數據庫鎖來保證只有一個節點執行任務 | 經過zookeeper的註冊與發現,能夠動態的添加服務器 | 基於競爭數據庫鎖保證只有一個節點執行任務,支持水平擴容。能夠手動增長定時任務,啓動和暫停任務,有監控 | 集羣部署,能夠動態的添加服務器。能夠手動增長定時任務,啓動和暫停任務。有監控 |
任務分片 | × | √ | √ | √ |
管理界面 | × | √ | √ | √ |
難易程度 | 簡單 | 簡單 | 簡單 | 略複雜 |
高級功能 | - | 彈性擴容,多種做業模式,失效轉移,運行狀態收集,多線程處理數據,冪等性,容錯處理,spring命名空間支持 | 彈性擴容,分片廣播,故障轉移,Rolling實時日誌,GLUE(支持在線編輯代碼,免發佈),任務進度監控,任務依賴,數據加密,郵件報警,運行報表,國際化 | 支持spring,spring boot,業務日誌記錄器,SPI擴展支持,故障轉移,節點監控,多樣化任務執行結果支持,FailStore容錯,動態擴容。 |
版本更新 | 半年沒更新 | 2年沒更新 | 最近有更新 | 1年沒更新 |
具體如何快速上手使用,官方文檔:www.xuxueli.com/xxl-job/ 已經介紹得比較詳細和清楚,再也不贅述
if (System.currentTimeMillis() - xxlRpcRequest.getCreateMillisTime() > 3*60*1000) {
xxlRpcResponse.setErrorMsg("The timestamp difference between admin and executor exceeds the limit.");
return xxlRpcResponse;
}
複製代碼
2 時區問題 任務由調度中心觸發,按照在調度中心設置任務的cron表達式觸發時,須要注意部署調度中心的機器所在的時區,按照該時區定製化cron表達式
3 任務執行中服務宕掉問題 調度中心完成任務下發,執行器在執行任務的過程當中,若是執行器忽然服務宕掉,會致使任務的執行問題在調度中心是執行中,調度中心並不會發起失敗重試。即便任務設置了超時時間,執行器宕掉致使致使任務長時間未執行完成,調度中心界面也不會看到任務超時,由於任務超時是由執行器檢測的並上報給調度中心的
所以遇到任務長時間未執行完成,能夠關注是否發生了執行器忽然服務宕掉
4 優雅停機問題 執行器執行任務基於線程池異步執行,當須要重啓時須要注意線程池中還有未執行完成任務的問題,須要優雅停機,能夠直接基於XxlJobExecutor.destroy()優雅停機,注意該方法在v2.0.2以前的版本存在bug致使沒法優雅停機,v2.0.2及以後的版本才修復(參考:github.com/xuxueli/xxl…)
5 失敗重試問題 當執行器節點部分服務不可用,例如節點磁盤損壞,但在調度中心仍然處於在線時,調度中心仍可能基於路由策略(包括故障轉移策略)路由到該未下線的節點,並不斷重試,不斷失敗,致使重試次數耗盡。因此路由策略儘可能不要採用固定化策略,例如固定第一個、固定最後一個
XXL-JOB上手仍是比較簡單,項目源碼仍是比較整潔,容易讀懂,學習以後能夠更加深刻理解分佈式系統設計、網絡通訊、多線程協同處理等知識點,推薦閱讀