鏈家分散式作業平臺

於玉桔發表於2018-11-12

背景

隨著貝殼的業務功能的不斷擴大,具有複雜功能的單體應用隨之進入了微服務開發的迭代模式。專案需要作業排程模組是個常見需求,在之前單體系統中,整合了quartz完成作業排程模組,因為單體應用整合一次後,單從技術層面看幾乎沒有新的工作量,而且整體還是比較穩定的,但是當單體應用進行微服務拆分後,很多微服務專案都需要整合作業排程模組,常規的一些作業排程實現,已經無法滿足公司級的微服務專案拓張,一種輕量級、分散式、統一管理的作業排程框架勢在必行。

cache redis

需求

  • 從公司角度的需求:由於單體應用改為微服務專案,微服務專案的作業排程功能百花齊放,作業排程系統在整體專案體系中屬於底層基礎元件專案,整體需易於接入公司的監控和規範,原理需完全掌握,如任務執行出現問題,要有及時的報警以便及時跟進,定時日報,彙總整體微服務系統作業排程情況。作業排程原理要100%的掌握,不允許線上出現技術原理不清而阻塞故障的修復。當接入作業越來越多時,要有負載機制,監控整體系統執行狀態。
  • 從業務系統角度的需求:作業排程系統要非常易於接入,且接入問題需要有專項小組提供解決方案,不能阻塞業務系統開發,作業需要靈活配置,且排程要準確。而且使用者手冊要足夠強大,作業排程專項小組在必要的情況下要持續支援有些快速開發的業務專案,因為這種突擊專案著重關心業務實現,根本不關心基礎元件實現細節,更不想遇到元件使用的阻塞。即:投入低,回報高。

技術調研

  • 在github上調研了目前比較流行作業排程專案,其大致可以分為一下幾個形態:
  • 1 深度優化定製Quartz形態:深度瞭解學習改造Quartz原始碼,將Quartz使用DB遷移至使用zk,通過開發後端管理系統操作zk,從而來管理整個作業排程任務的配置,這種形態的作業排程,原理上作業排程實現還是在客戶端完成,管理系統很弱化。這樣的作業排程系統有個與生俱來的優勢是:在管理系統出現故障時候也不會影響作業的繼續作業。因為客戶端專案幾乎整合全量的作業排程程式碼實現。
cache redis
  • 2 Quartz服務端形態:將Quartz抽象並封裝成服務端,客戶端通過基礎client-refence.jar完成任務的勾子方法暴露,服務端完成作業配置任務,當作業有任務觸發時,通過一種協議觸發客戶端專案任務的勾子方法,完成排程。這種形態的作業排程框架,客戶端一定程度減少了作業排程程式碼量,和專案效能消耗,但是帶來了很多分散式排程問題,需要深入瞭解整體排程的實現。
cache redis
  • 3 自實現排程系統,這種形態的作業排程系統基本都是功能非常多的,功能自實現一部分,也可通過SPI整合一部分,比如排程可以用Quartz實現,可有自身專案通過解析語法如:CronExpression.java實現Cron作業解析出未來一定時間內的任務,當時間到達觸發時間。觸發可支援客戶端整合,或通過一種協議觸發客戶端專案任務,完成排程。學習這類形態的作業排程架構,可以發人深省,無論從廣度或者深度,都可以使學習者對作業排程架構的認識更上一層樓。

思考與實踐

通過對作業系統的背景需求的認識,和在github進行的技術調研學習,結合我們自身特點,在實現自己的作業排程過程中,我們思考了如下幾點,

  • 排程設計與實現:客戶端暴露任務,通過註冊發現將任務與服務端資料同步,在服務端將發現到的任務自定義的組裝成作業,完成整體作業排程功能。服務端整合公司監控和規範。
    • 整體架構設計
      cache redis
    • 作業排程原理實現
      cache redis
  • 作業排程服務端高可用的實現方案:服務端通過zk主備選舉,完成服務端自身高可用實現,另外服務端暴露出健康介面,這裡我們公司有對服務健康介面的持續監測,如果叢集中,某個健康介面出現異常,會立刻報警給值班人員。
  • 作業排程服務端實現:這裡我們參考了大量技術調研第三種形態中功能實現,通過對排程底層實現方式的學習,實現任務在服務端可配置作業。
  • 如何做到客戶端極簡實現:作業排程需求專案通過整合client-refence.jar將任務方法暴露到註冊中心,並內部實現任務觸發方法,以便完成任務排程的觸發。這裡我們通過反射機制,通過在方法上增加特定註解,識別出此註解方法為任務方法。
  • 任務方法的註冊發現:前面說了客戶端的極簡實現,任務的註冊發現我們通過將識別出的任務方法,放到註冊中心上面,且通過心跳完成本地暴露任務與註冊中心的任務持續的一致性。
  • 專案許可權設計:隨之客戶端專案越來越多的接入作業平臺,肯定是需要一種許可權體系完成客戶端接入專案的邏輯隔離,這裡我們參考git專案人員管理體系,專案名稱為唯一標識,建立專案的同學為此專案的owner,可根據系統號邀請其他同學加入此專案,共同維護此專案作業配置。
  • 異常報警實現:定義異常事件型別,和內容,如:任務失敗事件,內容是異常資訊等,通過觀察者模式結合專案人員完成異常事件的實時報警。結合上面的許可權成員,立刻傳送給任務所在專案組成員。
  • 依賴、分片任務的實現:這裡我們參考了一些國外的科研專案,結合業內比較流行的設計,通過用有序無環圖(DAG)來實現任務的串聯依賴,與任務的平級分片。

總結

在深入學習作業排程框架的過程中,基本上所有框架解析Cron作業都是通過org.quartz.CronExpression.java實現解析的,之後通過解析出的觸發點,完成觸發。作業排程系統在整體專案中屬於很底層的基礎服務元件,很現實的問題是:很多業務專案其實對底層專案實現根本不關心,只要學習成本低,高可用,有專項小組維護,所以在做專案的設計實現的時候,要著重考慮使用者的核心訴求。作業排程系統在生成中每秒鐘中需要推送的任務很少,核心訴求並非高併發,所以我們設計的系統指標定義是秒級任務量的觸發延時指標,還有是底層系統一定要大而全,且學習成本低,提供一套預設的推薦配置,也要有高階滿足各個業務線常規的自定義配置,

cache redis

相關文章