1.業務場景java
保險人管系統每個月工資結算,平安有150萬代理人,如何快速的進行工資結算(數據運算型) 保險短信開門紅/電商雙十一 1000w+短信發送(短時匯聚型) 工做中業務場景很是多,所涉及到的場景也各不相同,這使得咱們定時任務系統應該集管理、調度、任務分配、監控預警爲一體的綜合調度系統,如何打造一套健壯的、適應不一樣場景的系統,技術選型尤爲重要。 針對以上場景咱們須要咱們的分佈式任務系統具有如下能力: 1.支持多種做業類型(shell做業/Java做業) 2.支持做業HA,負載均衡和失敗轉移 3.支持彈性擴容(應對開門紅以及促銷活動) 4.支持Job Timeout 處理 5.支持統一監控和告警 6.支持做業統一配置 7.支持資源隔離和做業隔離
2.定時任務調度的特色python
任務調度就是設點某一時間點自動觸發的任務,該任務能夠在時間規律上去循環執行。通常的技術quartz、spring task、java.util.Timer,這幾種若是在單一機器上跑其實問題不大,可是若是一旦應用於集羣環境作分佈式部署,就會帶來一個致命的問題,那就是重複執行,固然解決方案有,可是必須依賴數據庫,將任務執行狀態持久化下來。 特色: 時間驅動:系統通常能夠經過時間來驅動,定時定點定次。 批量處理:批量處理堆積的數據更加高效,在不須要實時性的狀況下比消息中間件更有優點。並且有的業務邏輯只能批量處理。如對帳批處理、資金管理系統回盤、部分銀行的報盤前的制盤 非實時性:定時任務不要求實時性,通常不用於C端用戶的交互,更多的用於業務數據的處理 隔離性/專注性:能夠跟其餘系統分離,只關注業務數據的處理,不影響用戶的操做和用戶系統的性能。 基本原理:
3.開源定時任務框架nginx
Quartz:Java事實上的定時任務標準。但Quartz關注點在於定時任務而非數據,並沒有一套根據數據處理而定製化的流程。雖然Quartz能夠基於數據庫實現做業的高可用,但缺乏分佈式並行調度的功能。 TBSchedule:阿里早期開源的分佈式任務調度系統。代碼略陳舊,使用timer而非線程池執行任務調度。衆所周知,timer在處理異常情況時是有缺陷的。並且TBSchedule做業類型較爲單一,只能是獲取/處理數據一種模式。還有就是文檔缺失比較嚴重。 Elastic-job:噹噹開發的彈性分佈式任務調度系統,功能豐富強大,採用zookeeper實現分佈式協調,實現任務高可用以及分片,目前是版本2.15,而且能夠支持雲開發,目前是版本2.15,如今已經不在更新。 Saturn:是惟品會自主研發的分佈式的定時任務的調度平臺,Saturn (任務調度系統)是惟品會開源的一個分佈式任務調度平臺,取代傳統的Linux Cron/Spring Batch Job的方式,作到全域統一配置,統一監控,任務高可用以及分片併發處理。Saturn是在噹噹開源的Elastic Job基礎上,結合各方需求和咱們的實踐看法改良而成,最新發布版本V3.3.1(2019年1月18日),最新測試版本V3.3.3.1。使用案例 惟品會、酷狗音樂、新網銀行、海融易、航美在線、量富徵信 xxl-job: 是大衆點評員工徐雪裏於2015年發佈的分佈式任務調度平臺,是一個輕量級分佈式任務調度框架,其核心設計目標是開發迅速、學習簡單、輕量級、易擴展,最新發布版本V2.0.2(2019.4.20日),其在惟品會內部已經發部署350+個節點,天天任務調度4000多萬次。同時,管理和統計也是它的亮點。使用案例 大衆點評、易信(IM)、京東(電商系統)、360金融(金融系統)、易企秀、隨行付(支付系統)、優信二手車
4.分佈式定時任務調度系統對比git
參與對比的可選系統方案: xxl-job(大衆點評開源)、Elastic-job(噹噹網開源)、Saturn(惟品會開源)github
4.1 項目背景以及社區力量算法
4.2 集羣部署spring
xxl-job: 基於Quartz的集羣方案,數據庫選用Mysql;集羣分佈式併發環境中使用QUARTZ定時任務調度,會在各個節點會上報任務,存到數據庫中,執行時會從數據庫中取出觸發器來執行,若是觸發器的名稱和執行時間相同,則只有一個節點去執行此任務。調度中心經過db配置區分不一樣集羣。 調度中心集羣部署時,幾點要求和建議: DB配置保持一致; 登錄帳號配置保持一致; 集羣機器時鐘保持一致(單機集羣忽視); 建議:推薦經過nginx爲調度中心集羣作負載均衡,分配域名。調度中心訪問、執行器回調配置、調用API服務等操做均經過該域名進行 Elastic-job: 重寫Quartz基於數據庫的分佈式功能,改用Zookeeper實現註冊中心 基於Zookeeper和其客戶端Curator實現的全局做業註冊控制中心。用於註冊,控制和協調分佈式做業執行。 Saturn: Saturn是Elastic-job的fork版本,因此saturn 也是用Zookeeper實現集羣的調度。 Saturn包括兩大部分,Saturn Console和Saturn Executor。 Saturn Console是一個GUI,用於做業/Executor管理,統計報表展示,系統配置等功能。它同時也是整個調度系統的大腦:將做業任務分配到各Executor。 爲了實現Console的高可用性,咱們都但願Console有多臺服務器所組成。咱們只須要在多臺不一樣的服務器的環境變量中指定相同的VIP_SATURN_CONSOLE_CLUSTER便可,至於VIP_SATURN_CONSOLE_CLUSTER的值,由你自行指定,只是一個集羣標識而已。 Saturn Executor是執行任務的Worker:按照做業配置的要求去執行部署於Executor所在容器或物理機當中的做業腳本和代碼。
4.3 多節點部署時任務不能重複執行sql
xxl-job: 使用Quartz基於數據庫的分佈式功能,爲保證系統"輕量級"而且下降學習部署成本,沒有采用Zookeeper做爲註冊中心,採用DB方式進行任務註冊發現 Elastic-job: 將任務拆分爲n個任務項後,各個服務器分別執行各自分配到的任務項。一旦有新的服務器加入集羣,或現有服務器下線,elastic-job將在保留本次任務執行不變的狀況下,下次任務開始前觸發任務重分片。 Saturn: 同Elastic-job
4.4 日誌可追溯docker
xxl-job: 支持,有日誌查詢界面 Elastic-job: 可經過事件訂閱的方式處理調度過程的重要事件,用於查詢、統計和監控。Elastic-Job目前提供了基於關係型數據庫兩種事件訂閱方式記錄事件。 Staturn: 支持日誌查看,同時支持jstack和gc log備份到executor日誌目錄(executor版本大於3.0.0)
4.5 監控告警shell
xxl-job: 任務調度失敗時郵件通知的郵箱地址,支持配置多郵箱地址,配置多個郵箱地址時用逗號分隔 Elastic-job: 經過事件訂閱方式可自行實現 做業運行狀態監控、監聽做業服務器存活、監聽近期數據處理成功、數據流類型做業(可經過監聽近期數據處理成功數判斷做業流量是否正常,若是小於做業正常處理的閥值,可選擇報警。)、監聽近期數據處理失敗(可經過監聽近期數據處理失敗數判斷做業處理結果,若是大於0,可選擇報警。) Staturn: 支持,須要本身接口實如今executor(SaturnSystemErrorGroup.java以及AbstractSaturnJob.java的實現)
4.6 彈性擴容縮容
xxl-job: 使用Quartz基於數據庫的分佈式功能,服務器超出必定數量會給數據庫形成必定的壓力,一旦有新執行器機器上線或者下線,下次調度時將會從新分配任務; Elastic-job: 經過zk實現各服務的註冊、控制及協調,如下是彈性分佈的實現: 第一臺服務器上線觸發主服務器選舉。主服務器一旦下線,則從新觸發選舉,選舉過程當中阻塞,只有主服務器選舉完成,纔會執行其餘任務。 某做業服務器上線時會自動將服務器信息註冊到註冊中心,下線時會自動更新服務器狀態。 主節點選舉,服務器上下線,分片總數變動均更新從新分片標記。 定時任務觸發時,如需從新分片,則經過主服務器分片,分片過程當中阻塞,分片結束後纔可執行任務。如分片過程當中主服務器下線,則先選舉主服務器,再分片。 經過上一項說明可知,爲了維持做業運行時的穩定性,運行過程當中只會標記分片狀態,不會從新分片。分片僅可能發生在下次任務觸發前。 每次分片都會按服務器IP排序,保證分片結果不會產生較大波動。 實現失效轉移功能,在某臺服務器執行完畢後主動抓取未分配的分片,而且在某臺服務器下線後主動尋找可用的服務器執行任務。 Staturn: 同上
4.7 支持並行調度
xxl-job: 執行器集羣部署時,任務路由策略選擇"分片廣播"狀況下,一次任務調度將會廣播觸發集羣中全部執行器執行一次任務,可根據分片參數處理分片任務 Elastic-job:: 採用任務分片方式實現。將一個任務拆分爲n個獨立的任務項,由分佈式的服務器並行執行各自分配到的分片項。 Staturn: 採用任務分片方式實現。將一個任務拆分爲n個獨立的任務項,由分佈式的服務器並行執行各自分配到的分片項。
4.8 高可用策略
xxl-job: 調度中心HA 經過DB鎖保證集羣分佈式調度的一致性, 一次任務調度只會觸發一次執行; 執行器支持集羣部署,提高調度系統可用性,同時提高任務處理能力。 執行器集羣部署時,幾點要求和建議: 執行器回調地址(xxl.job.admin.addresses)須要保持一致;執行器根據該配置進行執行器自動註冊等操做。 同一個執行器集羣內AppName(xxl.job.executor.appname)須要保持一致;調度中心根據該配置動態發現不一樣集羣的在線執行器列表 Elastic-job: 調度器的高可用是經過運行幾個指向同一個ZooKeeper集羣的Elastic-Job-Cloud-Scheduler實例來實現的。ZooKeeper用於在當前主Elastic-Job-Cloud-Scheduler實例失敗的狀況下執行領導者選舉。經過至少兩個調度器實例來構成集羣,集羣中只有一個調度器實例提供服務,其餘實例處於」待命」狀態。當該實例失敗時,集羣會選舉剩餘實例中的一個來繼續提供服務。 Saturn:同上
4.9 失敗處理策略
xxl-job: 調度失敗時的處理策略,策略包括:失敗告警(默認)、失敗重試; Elastic-job: 彈性擴容縮容在下次做業運行前重分片,但本次做業執行的過程當中,下線的服務器所分配的做業將不會從新被分配。失效轉移功能能夠在本次做業運行中用空閒服務器抓取孤兒做業分片執行。一樣失效轉移功能也會犧牲部分性能。 Saturn:支持異常檢測和自動失敗轉移 支持異常檢測和自動失敗轉移
4.10 動態分片策略
xxl-job: 分片廣播任務以執行器爲維度進行分片,支持動態擴容執行器集羣從而動態增長分片數量,協同進行業務處理;在進行大數據量業務操做時可顯著提高任務處理能力和速度。 執行器集羣部署時,任務路由策略選擇」分片廣播」狀況下,一次任務調度將會廣播觸發對應集羣中全部執行器執行一次任務,同時傳遞分片參數;可根據分片參數開發分片任務; Elastic-job:支持多種分片策略,可自定義分片策略 默認包含三種分片策略: 基於平均分配算法的分片策略、 做業名的哈希值奇偶數決定IP升降序算法的分片策略、根據做業名的哈希值對Job實例列表進行輪轉的分片策略,支持自定義分片策略 elastic-job的分片是經過zookeeper來實現的。分片的分片由主節點分配,以下三種狀況都會觸發主節點上的分片算法執行: a、新的Job實例加入集羣 b、現有的Job實例下線(若是下線的是leader節點,那麼先選舉而後觸發分片算法的執行) c、主節點選舉 Saturn:同Elastic-job
4.11 DAG(有向無環圖)
xxl-job: 待支持 支持簡單的子任務和任務依賴,不支持完整的DAG任務 Elastic-job:不支持 Saturn:支持做業編排,做業編排將做業造成一個有向無環圖,按照圖的順序依次調用。 該功能僅支持saturn 3.3.0及以上版 ![](https://oscimg.oschina.net/oscnet/8ba6bfa2947ac7df46843202bce7acfd328.jpg)
4.12 文檔
xxl-job: http://www.xuxueli.com/xxl-job/#/ 文檔詳細 Elastic-job: http://elasticjob.io/docs/elastic-job-lite/00-overview/ 基本部署、開發文檔 Saturn:https://vipshop.github.io/Saturn/#/ 基本部署、開發文檔
4.13 運維平臺
xxl-job: 可視化運維平臺: 登陸安全控制 日誌管理 執行器管理 調度中心 任務管理 報表查詢 支持實時查看運行數據,如任務數量、調度次數、執行器數量等;以及調度報表,如調度日期分佈圖,調度成功分佈圖等; Elastic-job: 可視化運維平臺: 登陸安全控制 註冊中心、事件追蹤數據源管理 快捷修改做業設置 做業和服務器維度狀態查看 操做做業禁用\啓用、中止和刪除等生命週期 事件追蹤查詢 Saturn: 可視化運維平臺: 登陸安全控制 系統配置 權限管理 註冊中心 告警中心 做業管理 自動運維 一鍵摘流量,一鍵dump以及Executor重啓。 報表展現
4.14 部署方式
xxl-job: 支持傳統JAR包啓動 支持容器化(Docker)部署 Elastic-job:自帶運維平臺 支持傳統JAR包啓動 Saturn:自帶運維平臺,可視化管理 支持容器化(Docker)部署 支持傳統JAR包啓動
4.15 觸發方式
xxl-job: 支持基於事件和時間觸發 Elastic-job: 支持基於時間觸發 Saturn:自帶運維平臺,可視化管理 支持基於事件和時間觸發
5.Quartz定時任務框架存在的問題
Quartz做爲開源做業調度中的佼佼者,是做業調度的首選。可是集羣環境中Quartz採用API的方式對任務進行管理,從而能夠避免上述問題,可是一樣存在如下問題:
問題一:調用API的的方式操做任務,不人性化; 問題二:須要持久化業務QuartzJobBean到底層數據表中,系統侵入性至關嚴重。 問題三:調度邏輯和QuartzJobBean耦合在同一個項目中,這將致使一個問題,在調度任務數量逐漸增多,同時調度任務邏輯逐漸加劇的狀況加,此時調度系統的性能將大大受限於業務; 問題四:quartz底層以「搶佔式」獲取DB鎖並由搶佔成功節點負責運行任務,會致使節點負載懸殊很是大; quartz的分佈式調度策略是以數據庫爲邊界資源的一種異步策略。各個調度器都遵照一個基於數據庫鎖的操做規則從而保證了操做的惟一性。同時多個節點的異步運行保證了服務的可靠。但這種策略有本身的侷限性:集羣特性對於高CPU使用率的任務效果很好,可是對於大量的短任務,各個節點都會搶佔數據庫鎖,這樣就出現大量的線程等待資源。這種狀況隨着節點的增長會愈來愈嚴重。 quartz的分佈式只是解決了高可用的問題,並無解決任務分片的問題,仍是會有單機處理的極限。
三大框架彌補了quartz的上述不足之處。
6.綜合對比
7.總結與結論
共同點: 三大框架都有普遍的用戶基礎和完整的技術文檔,都能知足定時任務的基本功能需求。 不一樣點: xxl-job: 大衆點評目前已接入XXL-JOB,內部別名《Ferrari》(Ferrari基於XXL-JOB的V1.1版本定製而成,新接入應用推薦升級最新版本)。 據最新統計, 自2016-01-21接入至2017-12-01期間,該系統已調度約100萬次,表現優異。新接入應用推薦使用最新版本,由於通過數十個版本的更新,系統的任務模型、UI交互模型以及底層調度通信模型都有了較大的優化和提高,核心功能更加穩定高效。 文檔比較詳細,xxl-job分爲調度中心(中心式)和執行器(分佈式),調度中心基於集羣Quartz實現並支持集羣部署,可保證調度中心HA;任務分佈式執行,任務"執行器"支持集羣部署,可保證任務執行HA,其中調度中心集羣基於DB,而其餘兩個框架用zookeeper崍實現分佈式鎖。 側重的業務實現的簡單和管理的方便,學習成本簡單,失敗策略和路由策略豐富。推薦使用在「用戶基數相對少,服務器數量在必定範圍內」的情景下使用,版本更新較快也是其一大亮點,支持子任務,DAG任務和依賴任務已經列入TODOLIST,暫時不支持秒任務,具體支持以下: 支持多種語言做業,語言無關(Java/Go/C++/PHP/Python/Ruby/shell) 分片廣播任務:執行器集羣部署時,任務路由策略選擇"分片廣播"狀況下,一次任務調度將會廣播觸發集羣中全部執行器執行一次任務,可根據分片參數開發分片任務; 動態分片:分片廣播任務以執行器爲維度進行分片,支持動態擴容執行器集羣從而動態增長分片數量,協同進行業務處理;在進行大數據量業務操做時可顯著提高任務處理能力和速度。 支持做業高可用 彈性擴容縮容:一旦有新執行器機器上線或者下線,下次調度時將會從新分配任務; 故障轉移:任務路由策略選擇"故障轉移"狀況下,若是執行器集羣中某一臺機器故障,將會自動Failover切換到一臺正常的執行器發送調度請求。 事件觸發:除了"Cron方式"和"任務依賴方式"觸發任務執行以外,支持基於事件的觸發任務方式。調度中心提供觸發任務單次執行的API服務,可根據業務事件靈活觸發。 任務依賴:支持配置子任務依賴,當父任務執行結束且執行成功後將會主動觸發一次子任務的執行, 多個子任務用逗號分隔; 容器化:提供官方docker鏡像,並實時更新推送dockerhub,進一步實現產品開箱即用; 任務失敗重試:支持自定義任務失敗重試次數,當任務失敗時將會按照預設的失敗重試次數主動進行重試;其中分片任務支持分片粒度的失敗重試; Elastic-job: 噹噹開源的分佈式調度解決方案,由兩個相互獨立的子項目Elastic-Job-Lite和Elastic-Job-Cloud組成。Elastic-Job-Lite定位爲輕量級無中心化解決方案,使用jar包的形式提供分佈式任務的協調服務。通常咱們只要使用Elastic-Job-Lite就好。 Elastic-Job-Lite並無宿主程序,而是基於部署做業框架的程序在到達相應時間點時各自觸發調度。它的開發也比較簡單,引用Jar包實現一些方法便可,最後編譯成Jar包運行。 Elastic-Job-Lite的分佈式部署全靠ZooKeeper來同步狀態和原數據。實現高可用的任務只需將分片總數設置爲1,並把開發的Jar包部署於多個服務器上執行,任務將會以1主N從的方式執行。一旦本次執行任務的服務器崩潰,其餘執行任務的服務器將會在下次做業啓動時選擇一個替補執行。若是開啓了失效轉移,那麼功能效果更好,能夠保證在本次做業執行時崩潰,備機之一當即啓動替補執行。 Elastic-Job-Lite的任務分片也是經過ZooKeeper來實現,Elastic-Job並不直接提供數據處理的功能,框架只會將分片項分配至各個運行中的做業服務器,開發者須要自行處理分片項與真實數據的對應關係。框架也預置了一些分片策略:平均分配算法策略,做業名哈希值奇偶數算法策略,輪轉分片策略。同時也提供了自定義分片策略的接口。 Elastic-Job-Lite還提供了一個任務監控和管理界面:Elastic-Job-Lite-Console。它和Elastic-Job-Lite是兩個徹底不關聯的應用程序,使用ZooKeeper來交換數據,管理人員能夠經過這個界面查看、監控和管理Elastic-Job-Lite的任務,必要的時候還能手動觸發任務。 關注的是數據,增長了彈性擴容和數據分片的思路,以便於更大限度的利用分佈式服務器的資源。可是學習成本相對高些,推薦在「數據量龐大,且部署服務器數量較多」時使用。 Staturn Saturn是惟品會在github開源的一款分佈式任務調度產品。它是基於噹噹elastic-job來開發的,其上完善了一些功能和添加了一些新的feature。Saturn的任務能夠用多種語言開發好比python、Go、Shell、Java、Php。其在惟品會內部已經發部署800+個節點,每日10億級別的調度考驗。 Saturn集成了Elastic-Job-Lite優勢的基礎上,在Elastic-Job停更後(一年多沒有更新維護),管理和統計也是它的亮點,同時版本更新比較快也是其一大亮點,具體支持詳情以下: 支持基於事件和時間觸發 支持多種語言做業,語言無關(Java/Go/C++/PHP/Python/Ruby/shell) 支持秒級調度 支持做業分片並行執行 支持依賴做業串行執行 支持做業高可用和智能負載均衡 支持異常檢測和自動失敗轉移 支持異地容災 支持多個集羣部署 支持跨機房區域部署 支持彈性動態擴容 支持優先級和權重設置 支持docker容器,容器化友好 支持cron時間表達式 支持多個時間段暫停執行控制 支持超時告警和超時強殺控制 支持灰度發佈 支持異常、超時和沒法高可用做業監控告警和簡易的故障排除 支持失敗率最高、最活躍和負荷最重的各域各節點TOP10的做業統計 經受住惟品會生產800多個節點,每日10億級別的調度考驗 支持簡單的DAG任務和依賴任務 可視化管理 結論: 結合以上三種分佈式定時任務調度系統的比對,在社區活躍和功能覆蓋來講,xxl-job和Saturn 比較適合目前系統的技術選型架構,其中xxl-job文檔詳細,入門簡單,不涉及zookeeper,相對來講學習成本低,可是性能瓶頸集中於DB,目前xxl-job項目組計劃替換Quartz崍解決目前存在的系統瓶頸,而反觀Saturn在集成了Elastic-job的優勢的前提下,補齊了管理和統計的短板,修復了歷史存留的問題,並有明確的發展計劃,已經成爲集管理、調度、任務分配、監控預警爲一體的綜合調度系統,因此更適合目前大部分系統現狀。