您好,登錄后才能下訂單哦!
無論是互聯網應用或者企業級應用,都充斥著大量的批處理任務。我們常常需要一些任務調度系統來幫助解決問題。隨著微服務化架構的逐步演進,單體架構逐漸演變為分布式、微服務架構。在此背景下,很多原先的任務調度平臺已經不能滿足業務系統的需求,于是出現了一些基于分布式的任務調度平臺。
在實際業務開發過程中,很多時候我們無可避免地需要使用一些定時任務來解決問題。通常我們會有多種解決方案:使用 Crontab 或 SpringCron (當然這種情況可能機器很少而且任務簡單又不是很多的情況下)。然而,當應用復雜度升高、定時任務數量增多且任務之間產生依賴關系時,Crontab 進行定時任務的管理配置就會非常混亂,嚴重影響工作效率。這時就會產生一系列問題:
隨著互聯網的發展,分布式服務架構勢越來越流行。相應的也需要一個分布式任務調度系統來管理分布式架構中的定時任務。
當垂直應用越來越多,應用之間交互也會越來越復雜,通常我們采用分布式或者微服務架構,將核心業務抽取出來,形成單獨的服務。一個獨立的微服務群體逐漸形成穩定的服務中心,使得業務應用能更快地響應多變的市場需求。
此時,用于提高業務復用及整合的分布式服務框架成為關鍵。同時,由于服務獨立,一般能做到定時任務獨立的情況,任務的更改對于整體系統的影響小之又小。通常我們會采用任務與調度分離的方式(如上圖所示),任務的執行邏輯無需關注調度與編排,同時可以保證執行器和調度的高可用,易于開發和維護。
在分布式服務架構的基礎上,由于獨立業務的數量可能很多,此時如果定時任務單獨在該服務中實現,很可能會出現難以管理的情況,且避免不了由于定時任務的更改而導致的業務重啟。因此,一個獨立的分布式任務調度系統是很必要的,可以用來全局統籌管理所有的定時任務。同時,將任務的配置單獨抽離出來,作為該分布式任務調度系統的功能,就能做到定時任務的更改不影響任何業務,也不影響整個系統:
SIA是宜信公司基礎開發平臺Simple is Awesome的簡稱,SIA-TASK(微服務任務調度平臺)是其中的一項重要產品,SIA-TASK契合當前微服務架構模式,具有跨平臺、可編排、高可用、無侵入、一致性、異步并行、動態擴展、實時監控等特點。
開源地址:https://github.com/siaorg/sia-task
我們先對比市場上主流的開源分布式任務調度框架,分析其優缺點,然后再介紹我們的技術選型。
下面我們簡單對比下 SIA-TASK 與這些任務調度框架:
任務編排 | 任務分片 | 跨平臺 | 高可用 | 故障轉移 | 實時監控 | |
---|---|---|---|---|---|---|
SIA-TASK | √ | √ | √ | √ | √ | √ |
Quartz | × | × | .NET | √ | × | API監控 |
TBSchedule | × | √ | × | √ | √ | √ |
Elastic-Job | × | √ | × | √ | √ | √ |
Saturn | × | √ | √ | √ | √ | √ |
Antares | √ | √ | × | √ | √ | √ |
Uncode-Schedule | × | × | × | √ | √ | √ |
XXL-JOB | 子任務依賴 | √ | × | √ | √ | √ |
可以發現,這些調度框架基本上都支持高可用、故障轉移與實時監控等功能,但是對于任務編排、任務分片與跨平臺等功能的支持各有側重點。SIA-TASK 將全面支持這些功能。
SIA-TASK借鑒微服務設計思想,獲取分布在每個執行器節點上的任務(Task)元數據,進行匯報,上傳注冊中心。利用在線可編輯方式支持任務在線編排、動態修改任務時鐘;使用 Http 協議作為交互傳輸協議。數據交互格式統一使用Json。用戶通過編排器(下文會做介紹)進行操作,觸發事件,調度器接收事件,由調度中心進行時鐘解析,執行任務流程,進行任務通知。
SIA-TASK 采用任務和調度分離的方式,業務的執行任務邏輯和調度邏輯完全分離。系統組成共涉及以下幾個核心概念:
SIA-TASK 可以分為三大模塊(調度中心、編排中心和執行器)、兩大組件(持久化存儲和注冊中心)。這三大模塊和兩大組件的作用如下:
SIA-TASK 使用 SpringBoot 體系作為架構選型,基于Quartz及Zookeeper進行二次開發,支持相應的特×××,SIA-TASK 的邏輯架構圖如下圖所示:
任務調度中心負責任務調度,管理調度信息,按照調度配置發出調度請求,自身不承擔業務代碼。調度系統與任務解耦,提高了系統可用性和穩定性,同時調度系統性能不再受限于任務模塊;支持可視化、簡單且動態地管理調度信息,包括任務新建,更新,刪除和任務報警等,所有上述操作都會實時生效,同時支持監控調度結果以及執行日志,支持執行器故障恢復。
任務編排中心是分布式調度中心支持在線任務模型編排的組件;依托于UI可進行web端任務編排。
我們可以通過上述基礎模型來編排一些復雜的調度模型,例如:
SIA-TASK的UI編排界面:
編排結束后查看task的編排信息如下圖所示:
同時,編排中心還提供首頁統計數據查看、調度監控、Job管理、Task管理以及日志管理功能。
負責接收調度請求并執行任務邏輯。任務模塊專注于任務的執行等操作,開發和維護更加簡單和高效;
執行器支持兩種類型:
(1) 如果使用 sia-task-hunter,支持SpringBoot項目和Spring項目, 引入 sia-task-hunter,任務(Task)抓取客戶端。合規的HTTP接口(稱之為Task)任務會自動被抓取并上傳注冊中心;
(2) 如果不使用 sia-task-hunter,只需提供任務可調用的HTTP接口,此時需要業務手動錄入,且自行控制該任務的并發調用控制。
分布式框架采用Zookeeper作為注冊中心。
(1) 任務注冊
調度中心和執行集群都以Zookeeper作為注冊中心,所有數據以節點及節點內容的形式注冊,通過定時匯報主機狀態保持存活在Zookeeper上。
(2) 元數據存儲
注冊中心不僅僅提供注冊服務,并且存儲每個執行器的信息(包括執行器實例信息,執行器上傳的Task元數據,以及任務運行時的一些臨時狀態數據)。
(3) 事件發布
基于Zookeeper事件推送機制,進行任務的發布,通過平衡算法保證調度器任務搶占的分布均衡。
(4) 負載均衡
保證調度器獲取執行Job的個數均衡,避免單一節點壓力。
這里采用MySQL作為數據持久化解決方案。
除了Task動態元數據保存在注冊中心之外,其他相關的元數據都存入MySQL,包括但不限于:手動錄入的Task、配置的Job信息、編排的Task依賴信息、調度日志、業務人員操作日志、Task執行日志等。
(1) 用戶可以通過UI進行Job創建。可以選擇Job類型,設置預警郵箱,設置Job描述。然后為創建的Job進行任務Task編排。
(2) Job創建完畢并且設置Task編排關系后可進行任務發布,通過UI對相應的Job進行操作(激活,執行一次,停止以及刪除操作)。
(3) 用戶的Task任務可以是通過抓取器抓取的,亦可以使用UI手動創建。
(1) Job創建完成之后,可以選擇激活觸發定時任務;
(2) Job到達預訂時間后,調度中心觸發Job,然后按照預定的Task編排邏輯通過http通知Task執行器進行執行,并異步監聽任務執行結果;
(3) 若執行結果成功,則判斷是否存在后置Task,若存在,則繼續下一次調度,若不存在,則說明該Job執行完畢,結束本次調用;若執行結果失敗,則觸發故障恢復策略:立即停止、忽略本次失敗、多次嘗試、轉到其它執行器執行。
Job在整個生命周期內存在四種狀態,分別是:已停止(NULL)、準備中(READY)、開始運行(RUNNING)、異常停止(STOP),狀態流轉及流轉條件如下圖所示。
SIA-TASK 的物理網絡拓撲圖如下所示:
SIA-TASK 的模塊間交互設計思路:
(1) 通過編排中心創建Task任務或通過Hunter自動抓取,并將 Task 信息異步保存到DB;創建Job并激活,在zookeeper中創建JobKey。
(2) 調度中心會監聽zookeeper中JobKey創建事件,然后搶占創建的Job,搶占成功后加入quartz定時任務,當時間到達即觸發Job運行。調度中心異步調用執行器服務執行Job中的 Task (可能存在多個 Task ,遵循 Task 失敗策略),并將結果返回到調度中心。
(3) 將Job執行狀態隨時在zookeeper上更改,通過編排中心的查詢接口可以進行查詢。
(4) Job執行結束后,等待下一次執行。
編排中心可以與DB和zookeeper進行數據交互,其主要功能可分為三方面:
編排中心首頁監控展示如下:
調度中心主要與DB、ZK和執行器進行交互,其主要功能可分為以下幾個方面:
執行器可以與ZK和調度中心進行交互,其主要功能可分為兩個方面:
執行器 Task示例:
@OnlineTask(description = "在線任務示例",enableSerial=true)
@RequestMapping(value = "/example", method = { RequestMethod.POST }, produces = "application/json;charset=UTF-8")
@CrossOrigin(methods = { RequestMethod.POST }, origins = "*")
@ResponseBody
public String example(@RequestBody String json) {
/**
* TODO:客戶端業務邏輯處理
*/
Map<String, String> info = new HashMap<String, String>();
info.put("status", "success");
info.put("result", "as you need");
return JSONHelper.toString(info);
}
由此可見,任務 Task 編寫非常簡單。
分布式服務一般都要考慮高可用方案,同樣 SIA-TASK 為了保證高可用,針對不同的服務組件進行了不同維度增強。
SIA-TASK 通過前后端分離、服務拆分等措施實現了編排中心的高可用。當集群中某實例失效后,不會影響集群的其它實例,因此無需特殊操作即可使用集群中其它的可用編排中心。
如果調度中心集群中的某個實例節點服務宕機后,這個實例節點上的所有Job會平滑遷移到集群中可用的實例上,不會造成定時任務的執行缺失,同時,當崩潰后的實例修復成功重新接入該集群時,會繼續搶占Job提供服務。
調度采用線程池方式實現,避免單線程因阻塞而引起任務調度延遲。程池里的線程數,默認值是10,當執行任務會并發執行多個耗時任務時,要根據業務特點選擇線程池的大小。
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 60
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
SIA-TASK 根據quartz自身提供的threadPool再次進行線程池的利用。進行線程池重新定義,針對每個Job去分配一個獨有的線程池。線程池的大小可根據Job自身編排的 Task 個數的大小進行動態伸縮,從而保證每個Job的調度線程完全獨立,不在會因為編排 Task 個數的陡增而耗盡線程資源。同時提供線程池資源的回收邏輯,在Job進行永久性終止時回收為期分配的線程池資源。
public static ExecutorService getExecutorService(String JobKey) {
ExecutorService exec = executorPool.get(JobKey);
if (exec == null) {
LOGGER.info(Constants.LOG_PREFIX + "Initialize thread pool for running Jobs,Job is {}",JobKey);
exec = Executors.newCachedThreadPool();
executorPool.putIfAbsent(JobKey, exec);
exec = executorPool.get(JobKey);
}
return exec;
}
SIA-TASK 針對Job的整個調度生命周期進行全面跟蹤,利用AOP進行日志增強,調度中心每觸發一次Job調度就會進行日志記錄。同時針對Job編排的 Task 執行也會進行記錄任務日志。
日志分為Job日志和 Task 日志:
public interface RestTemplate {
/**
* 異步Post方法 * @param request
* @param responseType
* @param uriVariables
* @param <T>
* @return
*/
<T> ListenableFuture<ResponseEntity<T>> postAsyncForEntity(Request request, Class<T> responseType, Object... uriVariables); }
SIA-TASK 從物理資源角度設計了調度資源池,出于一些特殊情況的考量我們針對調度器進行了池化;調度器可以通過不同的操作進行狀態的轉變,從而進行能力的轉化。
考慮網絡的不穩定性,SIA-TASK 針對網絡的不穩定性也做出了非常重要的設計,對于節點的連通性的測試支持以及針對 Task 運行實例節點健康的預感知,保證提前感知 Task 實例節點的健康情況,保證調度 Task 高可用。
同時也保證了執行器實例針對網絡導致鏈接中斷的問題,SIA-TASK 重新設計了zookeeper的重連機制,保證 Task 運行實例節點因網絡問題丟失鏈接后還能進行恢復重試,直到恢復正常后并入執行池中正常接收任務的調度。
至此對微服務任務調度平臺 SIA-TASK 做了一個簡要的介紹,包括設計背景、架構設計以及產品組件功能與特性。微服務任務調度平臺 SIA-TASK 基本上解決了當前的業務需求,提供簡單高效的編排調度服務。SIA-TASK 會持續迭代,提供更為完善的服務。之后也會提供相關技術文檔和使用文檔。
鏈接指南
開源地址:https://github.com/siaorg/sia-task
拓展閱讀:宜信開源微服務任務調度平臺(SIA-TASK)
作者:毛正衛/×××飛/梁鑫
原文首發:SpringCloud社區
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。