新一代分散式任務排程框架

程式設計師大彬發表於2023-04-11

本文已經收錄到Github倉庫,該倉庫包含計算機基礎、Java基礎、多執行緒、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~

Github地址

如果訪問不了Github,可以訪問gitee地址。

gitee地址

我們先思考下面幾個業務場景的解決方案:

  • 支付系統每天凌晨1點跑批,進行一天清算,每月1號進行上個月清算
  • 電商整點搶購,商品價格8點整開始優惠
  • 12306購票系統,超過30分鐘沒有成功支付訂單的,進行回收處理
  • 商品成功發貨後,需要向客戶傳送簡訊提醒
類似的業務場景非常多,我們怎麼解決?

為什麼我們需要定時任務

很多業務場景需要我們某一特定的時刻去做某件任務,定時任務解決的就是這種業務場景。一般來說,系統可以使用訊息傳遞代替部分定時任務,兩者有很多相似之處,可以相互替換場景。

如,上面發貨成功發簡訊通知客戶的業務場景,我們可以在發貨成功後傳送MQ訊息到佇列,然後去消費mq訊息,傳送簡訊。但在某些場景下不能互換:

  • 時間驅動/事件驅動:內部系統一般可以透過時間來驅動,但涉及到外部系統,則只能使用時間驅動。如怕取外部網站價格,每小時爬一次
  • 批次處理/逐條處理:批次處理堆積的資料更加高效,在不需要實時性的情況下比訊息中介軟體更有優勢。而且有的業務邏輯只能批次處理。如移動每個月結算我們的話費
  • 實時性/非實時性:訊息中介軟體能夠做到實時處理資料,但是有些情況下並不需要實時,比如:vip升級
  • 系統內部/系統解耦:定時任務排程一般是在系統內部,而訊息中介軟體可用於兩個系統間

java有哪些定時任務的框架

單機

  • timer:是一個定時器類,透過該類可以為指定的定時任務進行配置。TimerTask類是一個定時任務類,該類實現了Runnable介面,缺點異常未檢查會中止執行緒
  • ScheduledExecutorService:相對延遲或者週期作為定時任務排程,缺點沒有絕對的日期或者時間
  • spring定時框架:配置簡單功能較多,如果系統使用單機的話可以優先考慮spring定時器

分佈

  • Quartz:Java事實上的定時任務標準。但Quartz關注點在於定時任務而非資料,並無一套根據資料處理而定製化的流程。雖然Quartz可以基於資料庫實現作業的高可用,但缺少分散式並行排程的功能
  • TBSchedule:阿里早期開源的分散式任務排程系統。程式碼略陳舊,使用timer而非執行緒池執行任務排程。眾所周知,timer在處理異常狀況時是有缺陷的。而且TBSchedule作業型別較為單一,只能是獲取/處理資料一種模式。還有就是文件缺失比較嚴重
  • elastic-job:噹噹開發的彈性分散式任務排程系統,功能豐富強大,採用zookeeper實現分散式協調,實現任務高可用以及分片,目前是版本2.15,並且可以支援雲開發
  • Saturn:是唯品會自主研發的分散式的定時任務的排程平臺,基於噹噹的elastic-job 版本1開發,並且可以很好的部署到docker容器上。
  • xxl-job: 是大眾點評員工徐雪裡於2015年釋出的分散式任務排程平臺,是一個輕量級分散式任務排程框架,其核心設計目標是開發迅速、學習簡單、輕量級、易擴充套件。
最全面的Java面試網站

分散式任務排程系統對比

參與對比的可選系統方案:elastic——job (以下簡稱E-Job)與 xxx-job(以下簡稱X-Job)

支援叢集部署

X-Job:叢集部署唯一要求為:保證每個叢集節點配置(db和登陸賬號等)保持一致。排程中心透過db配置區分不同叢集。

執行器支援叢集部署,提升排程系統可用性,同時提升任務處理能力。叢集部署唯一要求為:保證叢集中每個執行器的配置項 “xxl.job.admin.addresses/排程中心地址” 保持一致,執行器根據該配置進行執行器自動註冊等操作。

E-Job:重寫Quartz基於資料庫的分散式功能,改用Zookeeper實現註冊中心

作業註冊中心:基於Zookeeper和其客戶端Curator實現的全域性作業註冊控制中心。用於註冊,控制和協調分散式作業執行。

多節點部署時任務不能重複執行

X-Job:使用Quartz基於資料庫的分散式功能

E-Job:將任務拆分為n個任務項後,各個伺服器分別執行各自分配到的任務項。一旦有新的伺服器加入叢集,或現有伺服器下線,elastic-job將在保留本次任務執行不變的情況下,下次任務開始前觸發任務重分片。

日誌可追溯

X-Job:支援,有日誌查詢介面

E-Job:可透過事件訂閱的方式處理排程過程的重要事件,用於查詢、統計和監控。Elastic-Job目前提供了基於關係型資料庫兩種事件訂閱方式記錄事件。

監控告警

X-Job:排程失敗時,將會觸發失敗報警,如傳送報警郵件。

任務排程失敗時郵件通知的郵箱地址,支援配置多郵箱地址,配置多個郵箱地址時用逗號分隔

E-Job:透過事件訂閱方式可自行實現

作業執行狀態監控、監聽作業伺服器存活、監聽近期資料處理成功、資料流型別作業(可透過監聽近期資料處理成功數判斷作業流量是否正常,如果小於作業正常處理的閥值,可選擇報警。)、監聽近期資料處理失敗(可透過監聽近期資料處理失敗數判斷作業處理結果,如果大於0,可選擇報警。)

彈性擴容縮容

X-Job:使用Quartz基於資料庫的分散式功能,伺服器超出一定數量會給資料庫造成一定的壓力

E-Job:透過zk實現各服務的註冊、控制及協調

支援並行排程

X-Job:排程系統多執行緒(預設10個執行緒)觸發排程執行,確保排程精確執行,不被堵塞。

E-Job:採用任務分片方式實現。將一個任務拆分為n個獨立的任務項,由分散式的伺服器並行執行各自分配到的分片項。

高可用策略

X-Job:“排程中心”透過DB鎖保證叢集分散式排程的一致性, 一次任務排程只會觸發一次執行;

E-Job:排程器的高可用是透過執行幾個指向同一個ZooKeeper叢集的Elastic-Job-Cloud-Scheduler例項來實現的。ZooKeeper用於在當前主Elastic-Job-Cloud-Scheduler例項失敗的情況下執行領導者選舉。透過至少兩個排程器例項來構成叢集,叢集中只有一個排程器例項提供服務,其他例項處於”待命”狀態。當該例項失敗時,叢集會選舉剩餘例項中的一個來繼續提供服務。

失敗處理策略

X-Job:排程失敗時的處理策略,策略包括:失敗告警(預設)、失敗重試;

E-Job:彈性擴容縮容在下次作業執行前重分片,但本次作業執行的過程中,下線的伺服器所分配的作業將不會重新被分配。失效轉移功能可以在本次作業執行中用空閒伺服器抓取孤兒作業分片執行。同樣失效轉移功能也會犧牲部分效能。

最全面的Java面試網站

動態分片策略

X-Job:分片廣播任務以執行器為維度進行分片,支援動態擴容執行器叢集從而動態增加分片數量,協同進行業務處理;在進行大資料量業務操作時可顯著提升任務處理能力和速度。

執行器叢集部署時,任務路由策略選擇”分片廣播”情況下,一次任務排程將會廣播觸發對應叢集中所有執行器執行一次任務,同時傳遞分片引數;可根據分片引數開發分片任務;

E-Job:支援多種分片策略,可自定義分片策略

預設包含三種分片策略:基於平均分配演算法的分片策略、 作業名的雜湊值奇偶數決定IP升降序演算法的分片策略、根據作業名的雜湊值對Job例項列表進行輪轉的分片策略,支援自定義分片策略

elastic-job的分片是透過zookeeper來實現的。分片的分片由主節點分配,如下三種情況都會觸發主節點上的分片演算法執行:a、新的Job例項加入叢集 b、現有的Job例項下線(如果下線的是leader節點,那麼先選舉然後觸發分片演算法的執行) c、主節點選舉”

和quartz框架對比

  • 呼叫API的的方式操作任務,不人性化;
  • 需要持久化業務QuartzJobBean到底層資料表中,系統侵入性相當嚴重。
  • 排程邏輯和QuartzJobBean耦合在同一個專案中,這將導致一個問題,在排程任務數量逐漸增多,同時排程任務邏輯逐漸加重的情況加,此時排程系統的效能將大大受限於業務;
  • Quartz關注點在於定時任務而非資料,並無一套根據資料處理而定製化的流程。雖然Quartz可以基於資料庫實現作業的高可用,但缺少分散式並行排程的功能。

綜合對比

總結和結論

共同點:

E-Job和X-job都有廣泛的使用者基礎和完整的技術文件,都能滿足定時任務的基本功能需求。

不同點:

  • X-Job 側重的業務實現的簡單和管理的方便,學習成本簡單,失敗策略和路由策略豐富。推薦使用在“使用者基數相對少,伺服器數量在一定範圍內”的情景下使
  • E-Job 關注的是資料,增加了彈性擴容和資料分片的思路,以便於更大限度的利用分散式伺服器的資源。但是學習成本相對高些,推薦在“資料量龐大,且部署伺服器數量較多”時使用

最後給大家分享一個Github倉庫,上面有大彬整理的300多本經典的計算機書籍PDF,包括C語言、C++、Java、Python、前端、資料庫、作業系統、計算機網路、資料結構和演算法、機器學習、程式設計人生等,可以star一下,下次找書直接在上面搜尋,倉庫持續更新中~

Github地址

相關文章