輕量級分布式任務調度平台(一、 XXL-JOB介紹、原理、工作流程)


XXL-JOB

【輕量級分布式任務調度平台】

(1) 基本介紹

XXL-JOB是一個輕量級分布式任務調度平台,主打特點是平台化,易部署,開發迅速、學習簡單、輕量級、易擴展,代碼仍在持續更新中。

  • 調度中心: 任務調度控制台,平台自身並不承擔業務邏輯,只是負責任務的統一管理和調度執行,並且提供任務管理平台

  • 執行器: 負責接收“調度中心”的調度並執行,可直接部署執行器,也可以將執行器集成到現有業務項目中。 通過將任務的調度控制和任務的執行解耦,業務使用只需要關注業務邏輯的開發。

  • XXL-JOB主要提供了任務的動態配置管理、任務監控和統計報表以及調度日志幾大功能模塊,支持多種運行模式和路由策略,可基於對應執行器機器集群數量進行簡單分片數據處理

(2) 框架源碼及文檔

源碼地址:

文檔地址:

(3)XXL-JOB的特性

  • 1、簡單:支持通過Web頁面對任務進行CRUD操作,操作簡單,一分鍾上手;
  • 2、動態:支持_動態修改任務狀態、啟動/停止任務,以及終止運行中任務,即時生效_;
  • 3、調度中心HA(中心式):調度采用中心式設計,調度中心自研調度組件並支持集群部署,可保證調度中心HA;
  • 4、執行器HA(分布式):任務分布式執行,任務"執行器"支持集群部署,可保證任務執行HA;
  • 5、注冊中心: 執行器會周期性自動注冊任務, 調度中心將會自動發現注冊的任務並觸發執行。也支持手動錄入執行器地址;
  • 6、彈性擴容縮容:一旦有新執行器機器上線或者下線,下次調度時將會重新分配任務;
  • 7、路由策略:執行器集群部署時提供豐富的路由策略,包括:_第一個、最后一個、輪詢、隨機、一致性HASH、最不經常使用、最近最久未使用、故障轉移、忙碌轉移_等;
  • 8、故障轉移:任務路由策略選擇_故障轉移_情況下,如果執行器集群中某一台機器故障,將會自動Failover切換到一台正常的執行器發送調度請求。
  • 9、阻塞處理策略:調度過於密集執行器來不及處理時的處理策略,策略包括:單機串行(默認)、丟棄后續調度、覆蓋之前調度
  • 10、任務超時控制:支持_自定義任務超時時間_,任務運行超時將會主動中斷任務;
  • 11、任務失敗重試:支持_自定義任務失敗重試次數_,當任務失敗時將會按照預設的失敗重試次數主動進行重試;其中分片任務支持分片粒度的失敗重試;
  • 12、任務失敗警告:默認提供郵件方式失敗告警,同時預留擴展接口,可方便的擴展短信、釘釘等告警方式;
  • 13、分片廣播任務:執行器集群部署時,任務路由策略選擇分片廣播情況下,一次任務調度將會廣播觸發集群中所有執行器執行一次任務,可根據分片參數開發分片任務;
  • 14、動態分片:分片廣播任務以執行器為維度進行分片,支持動態擴容執行器集群從而動態增加分片數量,協同進行業務處理;在進行大數據量業務操作時可顯著提升任務處理能力和速度。
  • 15、事件觸發:除了Cron方式任務依賴方式觸發任務執行之外,支持基於事件的觸發任務方式。調度中心提供觸發任務單次執行的API服務,可根據業務事件靈活觸發

(4) XXL-JOB架構圖

最新版本架構圖:

xxl-job其實也是在quartz的基礎上實現的,但是修改了任務調度的模式,並且任務調度采用注冊和RPC調用方式來實現。

管理后台頁面:

(5) XXL-JOB原理解析

2.1.0版本前核心調度模塊都是基於quartz框架,2.1.0版本開始自研調度組件,移除quartz依賴 ,使用時間輪調度。
(RPC的底層變化, 2.0.1 使用的是Jetty服務的RPC, 2.0.2 使用的Nettty服務的RPC)

(5.1) 定時觸發任務是如何實現的?:使用時間輪實現

  • xxl_job_info表是記錄定時任務的db表,里面有個trigger_next_time(Long)字段,表示下一次觸發的時間點任務時間被修改 / 每一次任務觸發后,可以根據cronb表達式計算下一次觸發時間戳:
    Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(new Date()))
    更新trigger_next_time字段
  • 定時執行任務邏輯:
    1. 定時任務scheduleThread:不斷從db5秒內要執行的任務讀出,立即觸發 / 放到時間輪等待觸發,並更新trigger_next_time
    2. 獲取當前時間now
    3. 輪詢db,找出trigger_next_time在距now 5秒內的任務
      3.1 對到達now時間后的任務(超出now 5秒外)
      ​ (1) 直接跳過不執行;
      ​ (2) 重置trigger_next_time
      3.2 對到達now時間后的任務(超出now 5秒內)
      ​ (1) 開線程執行觸發邏輯;
      ​ (2) 若任務下一次觸發時間是在5秒內,則放到時間輪內(Map<Integer, List >秒數(1-60) => 任務id列表);
      ​ (3) 重置 trigger_next_time
      3.3 對未到達 now時間的任務
      ​ (1)直接放到時間輪內;
      ​ (2)重置 trigger_next_time
    4. 定時任務ringThread:時間輪實現到點觸發任務
      4.1 時間輪數據結構:Map<Integer, List<Integer>> key是秒數(1-60)value是任務id列表
    5. 獲取當前時間秒數
    6. 從時間輪內移出當前秒數前2個秒數(避免處理耗時太長,跨過刻度,向前校驗一個刻度)的任務列表id,一一觸發任務;

(5.2) 如何避免集群中的多個服務器同時調度任務?

當xxl-job應用本身集群部署(實現高可用HA)時,如何避免集群中的多個服務器同時調度任務?
通過mysql悲觀鎖實現分布式鎖(for update語句)

  • setAutoCommit(false)關閉隱式自動提交事務,啟動事務
  • select lock for update(顯式排他鎖,其他事務無法進入&無法實現for update
  • db任務信息 -> 拉任務到內存時間輪 -> 更新db任務信息
  • commit提交事務,同時會釋放for update的排他鎖(悲觀鎖)

(5.3) 任務執行器注冊中心是如何實現的?

使用db表xxl_job_group記錄下執行器的信息:

執行器AppName、執行器名稱title、執行器地址列表address_list(多地址逗號分隔)

(5.4) 如何實現任務執行器的路由?

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

第一個、最后一個、輪詢、隨機、一致性HASH、最不經常使用、最近最久未使用、故障轉移、忙碌轉移等;

  • 第一個、最后一個、輪詢、隨機:都是簡單讀address_list即可
  • 一致性HASHTreeSet實現一致性hash算法
  • 最不經常使用、最近最久未使用HashMap、LinkedHashMap
  • 故障轉移:遍歷address_list獲取address時,逐個檢查該address的心跳(請求返回狀態);只有心跳正常的address才返回使用
  • 忙碌轉移:遍歷address_list獲取address時,逐個檢查該address是否忙碌(請求返回狀態);只有狀態為idleaddress才返回使用

(5.5) 如何實現任務分片、並行執行?

  • 拉出任務的執行機器列表,逐個設置index / total,把index / total分發到任務執行器
  • 任務執行器可根據index / total參數開發分片任務

(6)XXL-JOB任務調度流程

1:XXL-Jobadmin平台創建執行器(Job實際執行地址)
2:XXL-Jobadmin平台新建任務,填寫對應的執行器
3:Job服務器代碼中,使用JobHandler表示該類為Job執行方法
4:當任務執行的時候,會現在XXL-Jobadmin調度平台先執行一次,獲取任務中的執行器,然后去對應的執行器地址服務器,執行對應的任務


輕量級分布式任務調度平台XXL-JOB系列

輕量級分布式任務調度平台(一、 XXL-JOB介紹、原理、工作流程)
輕量級分布式任務調度平台(二、XXL-JOB環境搭建集成springboot)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM