歡迎光臨
每天分享高質量文章

點我達分散式任務排程系統-DaJob

點選上方“芋道原始碼”,選擇“置頂公眾號”

技術文章第一時間送達!

原始碼精品專欄

 

來源:點我達技術團隊

背景

    隨著網際網路的發展,應用服務中的定時任務數量日益增加,常規的垂直應用架構已無法應對,分散式服務架構勢在必行。同時,也迫切需要一個分散式任務排程系統來管理分散式服務中的定時任務。

單一應用架構

    當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,在該應用中的定時任務如果不多還好,但是一旦比較多,則意味著每次更改一個定時任務的執行時間,就需要重新部署一遍整個應用,導致整個應用停滯一段時間。

垂直應用架構

    當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆分為互不相干的幾個應用來提升效率。此時,相應的任務也會被垂直拆分,每次更改任務帶來的影響相應減少。

分散式服務架構

    當垂直應用越來越多,應用之間可能會出現不可避免的互動,此時,將核心業務抽取出來,形成單獨的服務,各式各樣的服務逐漸形成穩定的服務中心,使得前端應用能更快地響應多變的市場需求。此時,用於提高業務復用及整合的分散式服務框架是關鍵,同時,由於服務獨立,則一般能做到定時任務獨立的情況,因此,任務的更改對於整體系統的影響小之又小。

分散式任務排程

    在分散式服務架構的基礎上,由於獨立業務的數量可能很多,此時如果定時任務單獨在該服務中實現,很可能會出現難以管理的情況,且避免不了定時任務更改導致的業務重啟,因此,一個獨立的分散式任務排程系統是很必要的,可以用來全域性統籌管理所有的定時任務,同時,將任務的配置單獨抽離出來作為該分散式任務排程系統的功能,就能做到定時任務的更改不影響任何業務,也不影響整個系統。

架構設計

設計思想

    以Dubbo核心,將排程單獨抽象出來,成為一個排程中心,排程中心本身不承擔實現任何業務邏輯,只是單純依據排程配置來發起排程請求
    將任務抽象成為ExecutorService,由任務執行者來實現具體的任務,並且負責接收排程請求並執行,這樣設計可以將任務與排程中心完全解耦,提高整個系統的擴充套件性,方便接入
    將排程中心對任務執行者的一些呼叫操作提取出來,形成一個單獨的管理控制檯,可以用來檢視任務執行情況,同時該管理控制檯透過H5實現,並提供對外Restful API,方便擴充套件與接入
    透過各種中介軟體,實現一些必須的操作,例如告警,監控,日誌收集統計等操作,完全對整個系統安全性,穩定性的保障

  排程中心叢集透過Zookeeper儲存每個Schedular的一致性HashCode,以此來分配Job與Schedular之間的關係:新增的Job將會透過每個Schedular的一致性HashCode獲取其對應的Job數,依據Job數的大小以及Schedular的相關屬性來計算每個Schedular的權重,根據權重的大小來確定當前新增的Job應該被分配到哪個Schedular上。
    當新增Schedular之後,該新增的Schedular的Job正常為0,因此,正常狀態下,該新增的Schedular的權重會比較大。
    同時,排程中心透過Zookeeper對Schedular實現主備切換,確保系統穩定性

系統組成

Schedular

    基於Quartz實現排程,提供對執行者操作的介面,用於操作任務排程配置,排程觸發等操作;自身不參與任務邏輯的實現,不會受限於任務

執行者

    負責接收排程中心發起的排程請求,實現相應業務邏輯,完成任務執行,同時會對任務邏輯進行切麵處理,記錄相應日誌併在任務結束後傳送給排程中心

管理控制檯

    管理控制檯負責展示任務狀態,執行情況,任務執行日誌等報表資料,同時可以透過管理控制檯配置新增任務,操作任務的狀態,暫停/恢復等;另外,提供對外Restful API與H5的接入

Dubbo Monitor

    實時監控排程中心介面呼叫情況,統計排程頻次,成功失敗,QPS等,能透過這些報表資料來最佳化任務排程,最佳化系統

ELK

    透過ELK(ElasticSearch+Logstash+Kibana)來收集排程中心以及各執行機的執行日誌,並加以分析統計,形成報表,可以方便提供觀察

Alarm

    報警系統,透過Chronograf控制檯配置告警規則,在出現問題時第一時間透過Kapacitor進行郵件與簡訊報警,可以有效提高錯誤提示的及時性並且降低錯誤發生到錯誤解決過程中消耗的時間,降低生產環境造成的損失,告警資料透過業務儀錶盤獲取。例如:可以配置線上機器的cpu當前使用率,設定閥值50%,策略為超過設定閥值時簡訊告警,此時當線上某臺機器cpu超過50%時,即會傳送簡訊告警

業務儀錶盤

    透過打點的方式,來實時收集介面監控資料,透過logstash傳輸到kafka,透過kafka再分發到jstorm進行處理,處理完之後再儲存到influxdb,形成業務儀錶盤,最後透過Grafana控制檯產生監控報表

配置中心

    整個系統各服務,透過配置中心統一管理相應配置,形成分散式配置管理機制,方便系統內各服務的配置一致性以及準確性

 

   在使用上,對於接入者而言,只需做一些簡單的配置即可接入,接入介面簡單易懂

 在配置完之後,就可以實現自己的任務邏輯了

接入之後,可以透過日誌管理控制檯線上實時檢視任務執行狀態

    另外,由於有告警系統,在任務執行異常時,會產生告警郵件與簡訊,實時傳送,告知任務接入者與相應研發人員
  配置中心屬性配置

特性

   支援動態暫停/恢復任務

    任務狀態停止時,任務將不再被觸發,若任務在執行過程中被暫停,則正在執行的任務不會被阻塞(由於任務執行結果狀態中存在超時失敗狀態,因此如果點選暫停按鈕時阻塞了當前正在執行的任務,會使當前任務的執行狀態變為超時,不符合超時狀態真正的意義),會延遲停止,即等到當前任務執行完再真正停止任務
    排程中心基於Quartz實現,透過Zookeeper實現主備隔離,保證排程中心HA
     當活躍節點宕機,冷備節點就會載入所有活躍節點中正在排程狀態的任務,成為新的活躍節點,保證任務排程的準確執行
    執行機支援叢集部署,任務分散式執行,透過排程中心統一排程
     執行機負載均衡,預設根據任務在某個執行機上的執行次數計算執行機排程權重,按照權重來選擇本次任務排程分發給哪臺執行機,實現負載均衡,可手動更改執行機選擇策略

執行機叢集方式,

failover,failfast,failsafe,failback,forking,預設為failover(故障切換),呼叫失敗時,重試其他伺服器;failfast(快速失敗),只會發起一次呼叫,不會重試,失敗立即報錯;failsafe(失敗安全),出現異常時,直接忽略;failback(失敗恢復),呼叫失敗時,定時重發,直到成功,重啟會丟失; forking,並行呼叫多個執行機,只要一個成功即傳回

   分片任務,支援任務分片,透過引數傳送給任務執行機,執行機可以透過判斷引數來進行分片作業的開發,同時支援動態分片,以分片引數和執行機為緯度進行分片,支援動態擴容執行機以及分片引數

    例如,某張訂單表按照訂單ID來進行簡單緯度分片,且以取模3來進行分片,則可以設定三個分片引數,(0,1,2),執行機在透過context拿到其中的一個分片引數之後可以對該分片引數做判斷,來做具體的資料操作,例如當拿到的分片引數為0時,則對於0相應的分片做資料查詢操作,依次類推
    再例如,某張訂單表按照訂單ID和Status來進行二維分片,ID取模以3來進行分片,狀態以成功,失敗兩種狀態來進行分片,此時就可以設定6個分片引數,({‘id’:0,’status’:0},{‘id’:1,’status’:0},{‘id’:2,’status’:0},{‘id’:0,’status’:1},{‘id’:1,’status’:1},{‘id’:2,’status’:1}),執行機在透過context拿到其中的一個分片引數之後,就可以對其json引數進行判斷,來實現分片操作

   任務執行一致性,每次任務只會被一個執行機所執行;對於分片任務,在執行機叢集部署時,一次任務排程將會廣播觸發對應叢集中相應數量的執行器執行一次任務,同時傳遞分片引數,可根據分片引數開發分片任務。

    當分片引數大於執行器數量時,將會按照執行器路由策略,使得當前分片任務的某個或者某幾個執行機執行多個分片的任務

    例如:當前分片任務分片引數為(a,b,c),當前任務執行機有3臺(A,B,C)時,則會均勻隨機得將分片引數傳送給某一臺執行機,且三臺執行機一次只接收一個分片引數,做一次任務處理,即(a->A,b->B,c->C)|(a->A,b->C,c->B)|(a->B,b->A,c->C)|(a->B,b->C,c->A)|(a->C,b->A,c->B) |(a->C,b->B,c->A);

     當任務執行機只有2臺(A,B)時,每次任務排程時,某臺執行機會收到兩個分片引數,並分別處理這兩個分片引數,即(a->A,b->B,c->A)|(a->A,b->B,c->B)|(a->B,b->A,c->A)|(a->B,b->A,c->B);

     而當任務執行機大於分片引數個數,為4臺(A,B,C,D)時,(a->A,b->B,c->C)|(a->A,b->C,c->D)|(a->A,b->D,c->B)| (a->B,b->C,c->D)|(a->B,b->D,c->A)|(a->B,b->A,c->C)|(a->C,b->A,c->B)|(a->C,b->B,c->D)| (a->C,b->D,c->A)|(a->D,b->A,c->B)|(a->D,b->B,c->C)|(a->D,b->C,c->A),而統計下來,不管是執行機數目大於或者等於或者小於分片引數數目,被分發給執行機的分片引數始終是保持一致的(每臺執行機接收到的總的分片引數是均勻的)

    告警系統,系統接入內部告警系統,任務失敗時支援郵件,簡訊,釘釘,電話等告警

    彈性擴容縮容,排程中心將會實時探測任務執行機,因此一旦有執行機上線或者下線,都將會被探測到,而如果未被排程中心探測到,則可以進行手動探測執行機,而在探測到執行機之後,下次排程將會重新分配任務
    任務依賴,支援配置任務依賴關係,當父任務在執行完成之後會自動觸發子任務的執行
例如:有兩個任務,分別為A和B,而B的執行條件為確認A任務執行完,B才能執行,否則,B任務不執行,此時的依賴關係就是B任務依賴A任務,此時在A任務配置完之後,設定B任務為依賴任務,而依賴關係則是A;又例如有6個任務,分別是A1,A2,A3,A4,A5,B,而B任務的執行需要確保A1-5這5個任務都執行完,B任務才執行,此時,B的依賴關係就是B任務依賴於A1-5,此時在配置完A1-5這5個任務之後再設定B為依賴任務,依賴關係則是A1-5 

    支援執行時檢視任務執行情況,任務數量,呼叫次數,執行器數量等統計資訊
    異常執行恢復機制,有時會遇到不可控情況,即執行機在執行後的執行結果因為網路斷開等不可控因素導致不能傳送給排程中心,此時能透過異常執行恢復機制臨時記錄,在下次執行機正常啟動時重試傳送給排程中心
    排程手動觸發手動執行,特殊需求下,可能會要求排程可以手動執行,例如排程任務失敗之後可能需要手動執行一次排程來補償
    並行/序列策略,當定時時間遠大於任務執行時間時,可以使用並行策略,任務非同步呼叫執行,提高任務排程精確度;當任務執行時間可能大於定時時間,卻需要任務按照某個定時規則定時排程時,可以使用序列策略,排程中心排程的當前任務的上一次觸發,如果沒有執行完,則當前執行機的下一次定時時間點時不會被觸發,當且僅當任務執行結束,以防止某些持續性定時任務的時間不確定性導致非同步觸發時的資料混亂的情況發生,例如:某一任務的定時時間為10秒鐘,但是任務本身可能會出現執行超過10秒的情況,而超過時,如果出現兩個時間點的任務並行執行時會出現資料混亂的情況,此時就可以使用序列策略,確保當前執行機上一個任務未執行完,不會觸發新的執行
    支援排程介面資料監控,產生監控報表,便於觀測。

總結

   對於網際網路公司來說,時間就是金錢,效率決定一切。本系統在接入到8月初將近3個月的時間內,表現不凡,排程了約100萬次,給公司內部各服務實現任務排程提供了便利。




如果你對 Dubbo / Netty 等等原始碼與原理感興趣,歡迎加入我的知識星球一起交流。長按下方二維碼噢

目前在知識星球更新了《Dubbo 原始碼解析》目錄如下:

01. 除錯環境搭建
02. 專案結構一覽
03. 配置 Configuration
04. 核心流程一覽

05. 拓展機制 SPI

06. 執行緒池

07. 服務暴露 Export

08. 服務取用 Refer

09. 註冊中心 Registry

10. 動態編譯 Compile

11. 動態代理 Proxy

12. 服務呼叫 Invoke

13. 呼叫特性 

14. 過濾器 Filter

15. NIO 伺服器

16. P2P 伺服器

17. HTTP 伺服器

18. 序列化 Serialization

19. 叢集容錯 Cluster

20. 優雅停機

21. 日誌適配

22. 狀態檢查

23. 監控中心 Monitor

24. 管理中心 Admin

25. 運維命令 QOS

26. 鏈路追蹤 Tracing

… 一共 69+ 篇

目前在知識星球更新了《Netty 原始碼解析》目錄如下:

01. 除錯環境搭建
02. NIO 基礎
03. Netty 簡介
04. 啟動 Bootstrap

05. 事件輪詢 EventLoop

06. 通道管道 ChannelPipeline

07. 通道 Channel

08. 位元組緩衝區 ByteBuf

09. 通道處理器 ChannelHandler

10. 編解碼 Codec

11. 工具類 Util

… 一共 61+ 篇

目前在知識星球更新了《資料庫物體設計》目錄如下:


01. 商品模組
02. 交易模組
03. 營銷模組
04. 公用模組

… 一共 17+ 篇

原始碼不易↓↓↓

點贊支援老艿艿↓↓

贊(0)

分享創造快樂