一文讀懂分布式任務(wù)調(diào)度平臺XXL-JOB
本文公眾號來源:分布式系統(tǒng)架構(gòu)
作者:caison
本文已收錄至我的GitHub
基本介紹
同一服務(wù)多個實例的任務(wù)存在互斥時,需要統(tǒng)一協(xié)調(diào)
定時任務(wù)的執(zhí)行需要支持高可用、監(jiān)控運維、故障告警
需要統(tǒng)一管理和追蹤各個服務(wù)節(jié)點定時任務(wù)的運行情況,以及任務(wù)屬性信息,例如任務(wù)所屬服務(wù)、所屬責任人
功能特性
簡單靈活 提供Web頁面對任務(wù)進行管理,管理系統(tǒng)支持用戶管理、權(quán)限控制; 支持容器部署;支持通過通用HTTP提供跨平臺任務(wù)調(diào)度; 豐富的任務(wù)管理功能 支持頁面對任務(wù)CRUD操作; 支持在頁面編寫腳本任務(wù)、命令行任務(wù)、Java代碼任務(wù)并執(zhí)行; 支持任務(wù)級聯(lián)編排,父任務(wù)執(zhí)行結(jié)束后觸發(fā)子任務(wù)執(zhí)行; 支持設(shè)置任務(wù)優(yōu)先級; 支持設(shè)置指定任務(wù)執(zhí)行節(jié)點路由策略,包括輪詢、隨機、廣播、故障轉(zhuǎn)移、忙碌轉(zhuǎn)移等; 支持Cron方式、任務(wù)依賴、調(diào)度中心API接口方式觸發(fā)任務(wù)執(zhí)行 高性能 調(diào)度中心基于線程池多線程觸發(fā)調(diào)度任務(wù),快任務(wù)、慢任務(wù)基于線程池隔離調(diào)度,提供系統(tǒng)性能和穩(wěn)定性; 任務(wù)調(diào)度流程全異步化設(shè)計實現(xiàn),如異步調(diào)度、異步運行、異步回調(diào)等,有效對密集調(diào)度進行流量削峰; 高可用 任務(wù)調(diào)度中心、任務(wù)執(zhí)行節(jié)點均 集群部署,支持動態(tài)擴展、故障轉(zhuǎn)移 支持任務(wù)配置路由故障轉(zhuǎn)移策略,執(zhí)行器節(jié)點不可用是自動轉(zhuǎn)移到其他節(jié)點執(zhí)行 支持任務(wù)超時控制、失敗重試配置 支持任務(wù)處理阻塞策略:調(diào)度當任務(wù)執(zhí)行節(jié)點忙碌時來不及執(zhí)行任務(wù)的處理策略,包括:串行、拋棄、覆蓋策略 易于監(jiān)控運維 支持設(shè)置任務(wù)失敗郵件告警,預留接口支持短信、釘釘告警; 支持實時查看任務(wù)執(zhí)行運行數(shù)據(jù)統(tǒng)計圖表、任務(wù)進度監(jiān)控數(shù)據(jù)、任務(wù)完整執(zhí)行日志;
系統(tǒng)設(shè)計
1 設(shè)計思路
2 系統(tǒng)組成
調(diào)度模塊(調(diào)度中心):負責管理調(diào)度信息,按照調(diào)度配置發(fā)出調(diào)度請求,自身不承擔業(yè)務(wù)代碼。調(diào)度系統(tǒng)與任務(wù)解耦,提高了系統(tǒng)可用性和穩(wěn)定性,同時調(diào)度系統(tǒng)性能不再受限于任務(wù)模塊;支持可視化、簡單且動態(tài)的管理調(diào)度信息,包括任務(wù)新建,更新,刪除,任務(wù)報警等,所有上述操作都會實時生效,同時支持監(jiān)控調(diào)度結(jié)果以及執(zhí)行日志,支持執(zhí)行器Failover 執(zhí)行模塊(執(zhí)行器):負責接收調(diào)度請求并執(zhí)行任務(wù)邏輯。任務(wù)模塊專注于任務(wù)的執(zhí)行等操作,開發(fā)和維護更加簡單和高效;接收“調(diào)度中心”的執(zhí)行請求、終止請求和日志請求等

3 工作原理

任務(wù)執(zhí)行器根據(jù)配置的調(diào)度中心的地址,自動注冊到調(diào)度中心 達到任務(wù)觸發(fā)條件,調(diào)度中心下發(fā)任務(wù) 執(zhí)行器基于線程池執(zhí)行任務(wù),并把執(zhí)行結(jié)果放入內(nèi)存隊列中、把執(zhí)行日志寫入日志文件中 執(zhí)行器的回調(diào)線程消費內(nèi)存隊列中的執(zhí)行結(jié)果,主動上報給調(diào)度中心 當用戶在調(diào)度中心查看任務(wù)日志,調(diào)度中心請求任務(wù)執(zhí)行器,任務(wù)執(zhí)行器讀取任務(wù)日志文件并返回日志詳情
4 HA設(shè)計
4.1 調(diào)度中心高可用
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();
# 觸發(fā)任務(wù)調(diào)度
# 事務(wù)提交
conn.commit();
4.2 任務(wù)調(diào)度高可用
路由策略 ?調(diào)度中心基于路由策略路由選擇一個執(zhí)行器節(jié)點執(zhí)行任務(wù),XXL-JOB提供了如下路由策略保證任務(wù)調(diào)度高可用: 忙碌轉(zhuǎn)移策略:下發(fā)任務(wù)前向執(zhí)行器節(jié)點發(fā)起rpc心跳請求查詢是否忙碌,如果執(zhí)行器節(jié)點返回忙碌則轉(zhuǎn)移到其他執(zhí)行器節(jié)點執(zhí)行(參考 com.xxl.job.admin.core.route.strategy.ExecutorRouteBusyover) 故障轉(zhuǎn)移策略:下發(fā)任務(wù)前向執(zhí)行器節(jié)點發(fā)起rpc心跳請求查詢是否在線,如果執(zhí)行器節(jié)點沒返回或者返回不可用則轉(zhuǎn)移到其他執(zhí)行器節(jié)點執(zhí)行 (參考com.xxl.job.admin.core.route.strategy.ExecutorRouteFailover) 阻塞處理策略 ?當執(zhí)行器節(jié)點存在多個相同任務(wù)id的任務(wù)未執(zhí)行完成,則需要基于阻塞策略對任務(wù)進行取舍: 串行策略:默認策略,任務(wù)進行排隊、丟棄舊任務(wù)策略、丟棄新任務(wù)策略(參考:com.xxl.job.core.biz.impl.ExecutorBizImpl#run)
同類框架比較

使用
1 快速上手
2 注意事項
1 時鐘同步問題? 調(diào)度中心和任務(wù)執(zhí)行器需要時間同步,同步時間誤差需要在3分鐘內(nèi),否則拋出異常 參考:com.xxl.rpc.remoting.provider.XxlRpcProviderFactory#invokeService
if (System.currentTimeMillis() - xxlRpcRequest.getCreateMillisTime() > 3*60*1000) {
xxlRpcResponse.setErrorMsg("The timestamp difference between admin and executor exceeds the limit.");
return xxlRpcResponse;
}
2 時區(qū)問題 任務(wù)由調(diào)度中心觸發(fā),按照在調(diào)度中心設(shè)置任務(wù)的cron表達式觸發(fā)時,需要注意部署調(diào)度中心的機器所在的時區(qū),按照該時區(qū)定制化cron表達式 3 任務(wù)執(zhí)行中服務(wù)宕掉問題 調(diào)度中心完成任務(wù)下發(fā),執(zhí)行器在執(zhí)行任務(wù)的過程中,如果執(zhí)行器突然服務(wù)宕掉,會導致任務(wù)的執(zhí)行問題在調(diào)度中心是執(zhí)行中,調(diào)度中心并不會發(fā)起失敗重試。即使任務(wù)設(shè)置了超時時間,執(zhí)行器宕掉導致導致任務(wù)長時間未執(zhí)行完成,調(diào)度中心界面也不會看到任務(wù)超時,因為任務(wù)超時是由執(zhí)行器檢測的并上報給調(diào)度中心的
4 優(yōu)雅停機問題 執(zhí)行器執(zhí)行任務(wù)基于線程池異步執(zhí)行,當需要重啟時需要注意線程池中還有未執(zhí)行完成任務(wù)的問題,需要優(yōu)雅停機,可以直接基于XxlJobExecutor.destroy()優(yōu)雅停機,注意該方法在v2.0.2之前的版本存在bug導致無法優(yōu)雅停機,v2.0.2及之后的版本才修復(參考:https://github.com/xuxueli/xxl-job/issues/727) 5 失敗重試問題 當執(zhí)行器節(jié)點部分服務(wù)不可用,例如節(jié)點磁盤損壞,但在調(diào)度中心仍然處于在線時,調(diào)度中心仍可能基于路由策略(包括故障轉(zhuǎn)移策略)路由到該未下線的節(jié)點,并不斷重試,不斷失敗,導致重試次數(shù)耗盡。所以路由策略盡量不要采用固定化策略(例如固定第一個、固定最后一個策略)
總結(jié)
XXL-JOB上手還是比較簡單,項目源碼還是比較整潔,容易讀懂,學習之后可以更加深入理解分布式系統(tǒng)設(shè)計、網(wǎng)絡(luò)通信、多線程協(xié)同處理等知識點,推薦閱讀
參考
添加我的微信【sanwaiyihao】進一步交流和學習
評論
圖片
表情
