分佈式定時任務調度系統技術選型

轉:https://www.cnblogs.com/davidwang456/p/9057839.htmlhtml

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

  • 支付系統天天凌晨1點跑批,進行一天清算,每個月1號進行上個月清算
  • 電商整點搶購,商品價格8點整開始優惠
  • 12306購票系統,超過30分鐘沒有成功支付訂單的,進行回收處理
  • 商品成功發貨後,須要向客戶發送短信提醒

相似的業務場景很是多,咱們怎麼解決?java

爲何咱們須要定時任務

不少業務場景須要咱們某一特定的時刻去作某件任務,定時任務解決的就是這種業務場景。通常來講,系統可使用消息傳遞代替部分定時任務,二者有不少類似之處,能夠相互替換場景。如,上面發貨成功發短信通知客戶的業務場景,咱們能夠在發貨成功後發送MQ消息到隊列,而後去消費mq消息,發送短信。
但在某些場景下不能互換:git

a)時間驅動/事件驅動:內部系統通常能夠經過時間來驅動,但涉及到外部系統,則只能使用時間驅動。如怕取外部網站價格,每小時爬一次
b)批量處理/逐條處理:批量處理堆積的數據更加高效,在不須要實時性的狀況下比消息中間件更有優點。並且有的業務邏輯只能批量處理。如移動每月結算咱們的話費
c)實時性/非實時性:消息中間件可以作到實時處理數據,可是有些狀況下並不須要實時,好比:vip升級
d)系統內部/系統解耦:定時任務調度通常是在系統內部,而消息中間件可用於兩個系統間github

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年發佈的分佈式任務調度平臺,是一個輕量級分佈式任務調度框架,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展。

分佈式任務調度系統對比

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

項目背景及社區力量

X-Job : 大衆點評公司下員工許雪裏、貢獻者 3人; github有2470star、1015fork | QQ討論羣6個 | 有登記在使用的超過40家公司 | 文檔齊全
E-Job : 噹噹網開源,貢獻者17人; github有2524star、1015fork | QQ討論羣1個、源碼討論羣1個 | 有登記在使用的超過50家公司 | 文檔齊全 | 有明確的發展計劃spring

支持集羣部署

X-Job : 集羣部署惟一要求爲:保證每一個集羣節點配置(db和登錄帳號等)保持一致。調度中心經過db配置區分不一樣集羣。docker

執行器支持集羣部署,提高調度系統可用性,同時提高任務處理能力。集羣部署惟一要求爲:保證集羣中每一個執行器的配置項 「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 : 彈性擴容縮容在下次做業運行前重分片,但本次做業執行的過程當中,下線的服務器所分配的做業將不會從新被分配。失效轉移功能能夠在本次做業運行中用空閒服務器抓取孤兒做業分片執行。一樣失效轉移功能也會犧牲部分性能。

動態分片策略

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 關注的是數據,增長了彈性擴容和數據分片的思路,以便於更大限度的利用分佈式服務器的資源。可是學習成本相對高些,推薦在「數據量龐大,且部署服務器數量較多」時使用

附 定時任務的其餘方案

發貨後超過10天未收貨時系統自動確認收貨的多種實現方式

天天定時半夜篩選次日 能夠自動確認收貨的訂單,而後次日 每10分鐘 執行一次確認收貨 開銷不會太大吧 時間也相對精確

自動確認收貨這個狀態若是僅僅是讓客戶端看的話,等用戶下一次上線的時間,作一次運算就能夠了。

延遲和定時消息投遞ActiveMQ提供了一種broker端消息定時調度機制。適用於:一、不但願消息立刻被broker投遞出去,而是想要消息60秒之後發給消費者,二、想讓消息沒隔必定時間投遞一次,一共投遞指定的次數RabbitMQ能夠針對Queue和Message設置 x-message-tt,來控制消息的生存時間,若是超時,則消息變爲dead letter。利用DLX,當消息在一個隊列中變成死信後,它能被從新publish到另外一個Exchange。這時候消息就能夠從新被消費。

相關文章
相關標籤/搜索