俞珍秒,汪明貴
(南京南瑞信息通信科技有限公司,江蘇 南京 210003)
隨著現代信息技術的高速發展,企業的信息系統也充斥著大量的數據。為了合理地管理并利用這些數據,企業不得不對業務核心系統進行擴展,延伸出眾多業務子系統。而這些子系統為了滿足業務需求,又不得不嚴重依賴系統的核心數據。為了能有效地降低數據間的耦合,保證系統數據的一致性,業務系統通常會采用分布式任務調度系統來通知子系統的計算組件及時處理。但是核心數據的往往具有高頻變化特性,這給任務調度系統和業務子系統的穩定運行都提出了挑戰。
本文提供了一種基于異步式編程的分布式任務注冊及調度的實現方法,命名為CaesiumServer。CaesiumServer 通過異步式編程將任務注冊隊列中的任務分發至不同的處理單元,提高了任務注冊模塊的高效性。通過任務合并,避免了不必要的任務調度,保證了任務執行方的穩定運行。最后,多種任務執行策略能夠合理規劃資源,滿足不同場景下的任務調度需求。
在CaesiumServer 的設計中,任務接收模塊接收到注冊任務后,將任務信息中相同的任務進行合并后更新至任務池,以此保證相同的任務不會被多次重復觸發。此外,任務執行模塊在獲取任務池任務后,會根據任務性質直接啟動任務執行程序或發布任務執行信息。最后,任務執行方的執行控制器會根據任務注冊時指定的策略啟動任務執行程序。
在CaesiumServer 設計中調度引擎的任務接收模塊處理任務注冊信息。任務注冊方根據業務的需求將任務信息按照指定的格式發送到任務注冊隊列中,其中的任務信息主要包括:任務執行體ID、執行類、計劃開始執行時間、任務類型、任務觸發URL、是否可忽略、執行策略、執行計劃(Cron 表達式描述)、任務執行上下文等信息。
任務的接收模塊主要是通過異步式編程框架akka 來實現。akka 框架對構建高并發、高容錯性的分布式應用具有良好的支持。其中的akkaactor 模型是一種將行為定義到actor,actor 間通過消息通信,消息發送異步進行,消息處理(在actor 內)同步有序進行的一種高并發、非阻塞式編程模型。在CaesiumServer 設計中任務接收模塊主要定義了三種Actor,分別為:任務合并單元、更新處理單元、常規
處理單元。任務接收模塊從任務注冊隊列獲取任務信息后,會根據任務類型分別將任務信息分發至不同的Actor 進行處理。當任務類型為“可合并”型任務時,模塊會根據指定時間段內的相同內容合并成一條任務后,發送至待執行任務池。當任務類型為“更新”型任務時,會判斷當前待執行任務池中是否存在未被執行的相同任務,如果存在會將本次任務中的包含的信息更新至待執行任務池;如果不存在則將本次任務發送至待執行任務池。當任務類型為“常規”型任務時,則將本次任務直接發送至待執行任務池。
處理任務注冊信息中如何快速、高效的處理注冊任務是其難點,因為應用注冊方會同時注冊大批量的任務。此時通過akka 的事件驅動機制及時觸發相應的邏輯尤為重要。
CaesiumServer的任務執行模塊以定期檢查的方式,根據待執行任務池中的任務信息判斷當前任務是否需要被執行。當任務需要被執行時,首先會查看該任務信息中任務觸發URL 是否有設定值。如果有設定值,會通過異步調用該觸發URL 來啟動任務執行體;如果未設定任務觸發URL,就會將任務信息發送至任務執行隊列。在任務觸發完成后,會根據任務的執行計劃更新或刪除任務池中的任務。
任務執行方從任務執行隊列中獲取“任務執行體ID”與自身一致的待執行任務信息后,將任務交由任務執行控制器進行處理。任務執行控制器主要包含一個分發線程、一個執行線程池。分發線程主要按照任務的“執行策略”控制任務執行類以不同的方式執行。“執行策略”主要包括“隊列”、“并行”、“取消當前”、“忽略當前”、“延遲”等方式。執行線程池主要用來執行各任務。
當任務的執行策略為“隊列”方式時:分發線程會將任務按照“執行類”為單位,為該執行類創建一個執行隊列,依次將任務發送至執行線程池中執行,直到將執行隊列中的任務全部執行完成。
當任務的執行策略為“并行”方式時:分發線程會直接將該任務發送至執行線程池中執行。
當任務的執行策略為“取消當前”方式時:分發線程會判斷任務執行線程池中是否存在與本任務相同的“執行類”在運行,如果存在則調用當前任務的取消邏輯,待取消成功后將本次任務發送至執行線程池中執行。如果不存在,直接將該任務發送至執行線程池中執行。
當任務的執行策略為“忽略當前”方式時:分發線程會判斷任務執行線程池中是否存在與本任務相同的“執行類”在運行,如果存在則舍棄當前的任務,不對本次任務做任何處理。如果不存在,直接將該任務發送至執行線程池中執行。
當任務的執行策略為“延遲”方式時:分發線程會按照“執行類”為單位記錄前次任務執行時間,如果當前時間超過延遲時間時,將本次任務發送至執行線程池中執行;如果尚未達到延遲時間會創建一個定時器,在時間到達時將任務發送至執行線程池中執行。
不同執行策略的處理方式各異,實現難度也各異。其中“取消當前”型任務處理難度較大。因為所有的任務都是在任務執行線程池中運行,如何獲取當前任務的引用以及如何判斷任務取消成功也是一個處理難點。實施時可通過包裝類對方式對“取消當前”型任務進行封裝,包裝類可設計成包含當前任務、前次任務等信息。包裝類的執行方法中首先需要調用前次任務的取消方法,直到取消成功后再調用當前任務的執行方法。
CaesiumServer 可保證任務調度引擎的高效性、穩定性、容錯性,改變了以往任務調度引擎的過載帶來的任務觸發不及時、丟失等狀況。能夠顯著加強任務執行方的處理效率,特別是根據任務特征選擇不同的執行策略能夠合理的優化服務器資源,改變了以往任務執行方大量任務同時執行帶來的服務器壓力,甚至崩潰的風險。