版權(quán)歸原作者所有,如有侵權(quán),請聯(lián)系我們

淺談分布式定時(shí)任務(wù)調(diào)度

中移科協(xié)
原創(chuàng)
有用的科技知識又增加了
收藏

在平時(shí)的業(yè)務(wù)場景中,經(jīng)常有一些場景需要使用定時(shí)任務(wù),而且對于現(xiàn)在快速消費(fèi)的時(shí)代,每天都需要發(fā)送各種推送,消息都需要依賴定時(shí)任務(wù)去完成,應(yīng)用非常廣泛,這時(shí)候選擇一個(gè)好的定時(shí)任務(wù)調(diào)度系統(tǒng)就顯得尤為重要。

1.1 什么是定時(shí)任務(wù)

定時(shí)任務(wù)是按照指定時(shí)間周期運(yùn)行任務(wù)。使用場景為在某個(gè)固定時(shí)間點(diǎn)執(zhí)行,或者周期性的去執(zhí)行某個(gè)任務(wù),比如:每天晚上24點(diǎn)做數(shù)據(jù)匯總,定時(shí)發(fā)送短信等。

1.2 常見定時(shí)任務(wù)方案

While + Sleep : 通過循環(huán)加休眠的方式定時(shí)執(zhí)行。

Timer和TimerTask實(shí)現(xiàn) :JDK自帶的定時(shí)任務(wù),可以實(shí)現(xiàn)簡單的間隔執(zhí)行任務(wù)(在指定時(shí)間點(diǎn)執(zhí)行某一任務(wù),也能定時(shí)的周期性執(zhí)行),無法實(shí)現(xiàn)按日歷去調(diào)度執(zhí)行任務(wù)。

ScheduledExecutorService : Java并發(fā)包下,JDK1.5出現(xiàn),是比較理想的定時(shí)任務(wù)實(shí)現(xiàn)方案。Eureka就使用的是它。

QuartZ :使用Quartz,它是一個(gè)異步任務(wù)調(diào)度框架,功能豐富,可以實(shí)現(xiàn)按日歷調(diào)度,支持持久化。

使用Spring Task:Spring 3.0后提供Spring Task實(shí)現(xiàn)任務(wù)調(diào)度,支持按日歷調(diào)度,相比Quartz功能稍簡單,但是在開發(fā)基本夠用,支持注解編程方式。

pringBoot中的Schedule :通過@EnableScheduling+@Scheduled最實(shí)現(xiàn)定時(shí)任務(wù),底層使用的是Spring Task。

1.3 分布式定時(shí)任務(wù)面臨的問題

上述的定時(shí)任務(wù)都是集中式(單體項(xiàng)目使用)的定時(shí)任務(wù),在分布式中將會面臨一些問題或不足

業(yè)務(wù)量大,單機(jī)性能瓶頸需要擴(kuò)展;

多臺機(jī)器部署如何保證定時(shí)任務(wù)不重復(fù)執(zhí)行;

定時(shí)任務(wù)時(shí)間需要可調(diào)整,可以暫停;

機(jī)器發(fā)生故障down機(jī),定時(shí)任務(wù)依然可用,如何實(shí)現(xiàn)故障轉(zhuǎn)移;

定時(shí)任務(wù),執(zhí)行日志是否可監(jiān)控。

1.4 分布式定時(shí)任務(wù)面臨的問題

執(zhí)行器:批量運(yùn)行程序,即實(shí)際運(yùn)行作業(yè)邏輯的進(jìn)程;

執(zhí)行器組:邏輯概念,是多個(gè)執(zhí)行器的集合。每個(gè)作業(yè)都需要綁定一個(gè)執(zhí)行器組,根據(jù)作業(yè)所配置的路由策略進(jìn)行派發(fā);

作業(yè)JOB:作業(yè)是批量邏輯的載體,是批量運(yùn)行的最小單位;在Java里,作業(yè)對應(yīng)的就是一個(gè)方法函數(shù);在shell里,作業(yè)對應(yīng)的就是一個(gè)sh腳本。

任務(wù)Task:任務(wù)是作業(yè)編排的容器,是多個(gè)作業(yè)如何有序運(yùn)行的工作流定義。

1.5 分布式定時(shí)任務(wù)xxl-job

XXL-JOB是一個(gè)分布式任務(wù)調(diào)度平臺,于2015問世,其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡單、輕量級、易擴(kuò)展?,F(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用。其具備且不止如下能力:

簡單:支持通過Web頁面對任務(wù)進(jìn)行CRUD操作,操作簡單,一分鐘上手;

動態(tài):支持動態(tài)修改任務(wù)狀態(tài)、啟動/停止任務(wù),以及終止運(yùn)行中任務(wù),即時(shí)生效;

調(diào)度中心HA(中心式):調(diào)度采用中心式設(shè)計(jì),“調(diào)度中心”基于集群Quartz實(shí)現(xiàn)并支持集群部署,可保證調(diào)度中心HA;

執(zhí)行器HA(分布式):任務(wù)分布式執(zhí)行,任務(wù)"執(zhí)行器"支持集群部署,可保證任務(wù)執(zhí)行HA;

彈性擴(kuò)容縮容:一旦有新執(zhí)行器機(jī)器上線或者下線,下次調(diào)度時(shí)將會重新分配任務(wù);

路由策略:執(zhí)行器集群部署時(shí)提供豐富的路由策略,包括:第一個(gè)、最后一個(gè)、輪詢、隨機(jī)、一致- 性HASH、最不經(jīng)常使用、最近最久未使用、故障轉(zhuǎn)移、忙碌轉(zhuǎn)移等;

故障轉(zhuǎn)移:任務(wù)路由策略選擇"故障轉(zhuǎn)移"情況下,如果執(zhí)行器集群中某一臺機(jī)器故障,將會自動Failover切換到一臺正常的執(zhí)行器發(fā)送調(diào)度請求。

任務(wù)失敗告警:默認(rèn)提供郵件方式失敗告警,同時(shí)預(yù)留擴(kuò)展接口,可方面的擴(kuò)展短信、釘釘?shù)雀婢绞剑?/p>

2、xxl-job架構(gòu)設(shè)計(jì)

2.1 設(shè)計(jì)思想

將調(diào)度行為抽象形成“調(diào)度中心”公共平臺,而平臺自身并不承擔(dān)業(yè)務(wù)邏輯,“調(diào)度中心”負(fù)責(zé)發(fā)起調(diào)度請求。

將任務(wù)抽象成分散的JobHandler,交由“執(zhí)行器”統(tǒng)一管理,“執(zhí)行器”負(fù)責(zé)接收調(diào)度請求并執(zhí)行對應(yīng)的JobHandler中業(yè)務(wù)邏輯。因此,“調(diào)度”和“任務(wù)”兩部分可以相互解耦,提高系統(tǒng)整體穩(wěn)定性和擴(kuò)展性;

2.2 架構(gòu)設(shè)計(jì)圖

xxl-job分為調(diào)度中心和執(zhí)行器兩大模塊。

2.2.1 調(diào)度模塊(調(diào)度中心)

負(fù)責(zé)管理調(diào)度信息,按照調(diào)度配置發(fā)出調(diào)度請求,自身不承擔(dān)業(yè)務(wù)代碼。調(diào)度系統(tǒng)與任務(wù)解耦,提高了系統(tǒng)可用性和穩(wěn)定性,同時(shí)調(diào)度系統(tǒng)性能不再受限于任務(wù)模塊;

支持可視化、簡單且動態(tài)的管理調(diào)度信息,包括任務(wù)新建,更新,刪除,GLUE開發(fā)和任務(wù)報(bào)警等,所有上述操作都會實(shí)時(shí)生效,同時(shí)支持監(jiān)控調(diào)度結(jié)果以及執(zhí)行日志,支持執(zhí)行器Failover(故障轉(zhuǎn)移)。

2.2.2 執(zhí)行模塊(執(zhí)行器)

負(fù)責(zé)接收調(diào)度請求并執(zhí)行任務(wù)邏輯。任務(wù)模塊專注于任務(wù)的執(zhí)行等操作,開發(fā)和維護(hù)更加簡單和高效;

接收“調(diào)度中心”的執(zhí)行請求、終止請求和日志請求等。

XXL-JOB架構(gòu)圖V2.1.0

2.2.3 調(diào)度中心高可用

基于數(shù)據(jù)庫的集群方案,數(shù)據(jù)庫選用Mysql;集群分布式并發(fā)環(huán)境中進(jìn)行定時(shí)任務(wù)調(diào)度時(shí),會在各個(gè)節(jié)點(diǎn)會上報(bào)任務(wù),存到數(shù)據(jù)庫中,執(zhí)行時(shí)會從數(shù)據(jù)庫中取出觸發(fā)器來執(zhí)行,如果觸發(fā)器的名稱和執(zhí)行時(shí)間相同,則只有一個(gè)節(jié)點(diǎn)去執(zhí)行此任務(wù)。

2.2.4并行調(diào)度

調(diào)度采用線程池方式實(shí)現(xiàn),避免單線程因阻塞而引起任務(wù)調(diào)度延遲。XXL-JOB調(diào)度模塊默認(rèn)采用并行機(jī)制,在多線程調(diào)度的情況下,調(diào)度模塊被阻塞的幾率很低,大大提高了調(diào)度系統(tǒng)的承載量。

XXL-JOB的不同任務(wù)之間并行調(diào)度、并行執(zhí)行。XXL-JOB的單個(gè)任務(wù),針對多個(gè)執(zhí)行器是并行運(yùn)行的,針對單個(gè)執(zhí)行器是串行執(zhí)行的。同時(shí)支持任務(wù)終止。

2.2.5執(zhí)行器(任務(wù))高可用

執(zhí)行器如若集群部署,調(diào)度中心將會感知到在線的所有執(zhí)行器,如“127.0.0.1:9997, 127.0.0.1:9998, 127.0.0.1:9999”。多個(gè)執(zhí)行器可以選擇“路由策略”來采用輪詢,隨機(jī)等方式進(jìn)行多機(jī)器調(diào)度。

當(dāng)任務(wù)”路由策略”選擇”故障轉(zhuǎn)移(FAILOVER)”時(shí),當(dāng)調(diào)度中心每次發(fā)起調(diào)度請求時(shí),會按照順序?qū)?zhí)行器發(fā)出心跳檢測請求,第一個(gè)檢測為存活狀態(tài)的執(zhí)行器將會被選定并發(fā)送調(diào)度請求。調(diào)度成功后,可在日志監(jiān)控界面查看“調(diào)度備注”

3、xxl-job具體實(shí)踐

3.1.下載源碼
請下載項(xiàng)目源碼并解壓,使用IDEA工具導(dǎo)入項(xiàng)目
源碼倉庫地址

https://github.com/xuxueli/xxl-job

項(xiàng)目代碼結(jié)構(gòu)如下:

3.2. 導(dǎo)入數(shù)據(jù)庫

打開項(xiàng)目代碼,獲取 “調(diào)度數(shù)據(jù)庫初始化SQL腳本” 并執(zhí)行即可。

“調(diào)度數(shù)據(jù)庫初始化SQL腳本” 位置為:

xxl-job/doc/db/tables_xxl_job.sql

數(shù)據(jù)庫名:xxl_job

xxl_job_lock:任務(wù)調(diào)度鎖表;

xxl_job_group:執(zhí)行器信息表,維護(hù)任務(wù)執(zhí)行器信息;

xxl_job_info:調(diào)度擴(kuò)展信息表:用于保存XXL-JOB調(diào)度任務(wù)的擴(kuò)展信息,如任務(wù)分組、任務(wù)名、機(jī)器地址、執(zhí)行器、執(zhí)行入?yún)⒑蛨?bào)警郵件等等;

xxl_job_log:調(diào)度日志表:用于保存XXL-JOB任務(wù)調(diào)度的歷史信息,如調(diào)度結(jié)果、執(zhí)行結(jié)果、調(diào)度入?yún)?、調(diào)度機(jī)器和執(zhí)行器等等;

xxl_job_log_report:調(diào)度日志報(bào)表:用戶存儲XXL-JOB任務(wù)調(diào)度日志的報(bào)表,調(diào)度中心報(bào)表功能頁面會用到;

xxl_job_logglue:任務(wù)GLUE日志:用于保存GLUE更新歷史,用于支持GLUE的版本回溯功能;

xxl_job_registry:執(zhí)行器注冊表,維護(hù)在線的執(zhí)行器和調(diào)度中心機(jī)器地址信息;

xxl_job_user:系統(tǒng)用戶表;

3.3. 啟動調(diào)度中心

打開 xxl-job-admin 的配置文件,

xxl-job/xxl-job-admin/src/main/resources/application.properties

對調(diào)度中心進(jìn)行配置,重要配置如下:

server.port : 根據(jù)情況修改端口

spring.datasource.url :指向剛才準(zhǔn)備的數(shù)據(jù)庫

spring.datasource.password : 記得修改成自己的數(shù)據(jù)庫密碼

spring.mail.username :配置自己的郵件賬號

spring.mail.password :郵件的授權(quán)碼

根據(jù)自己的情況進(jìn)行修改,然后啟動調(diào)度中心 ,執(zhí)行XxlJobAdminApplication#main 方法 ,啟動之后,瀏覽器訪問

http://localhost:8080/xxl-job-admin;

注意URL中有個(gè)上下文路徑。默認(rèn)登錄賬號 admin/123456, 登錄后運(yùn)行界面如下圖所示。

評論
祥和123
庶吉士級
已閱知
2024-04-28
Ljh春暖花開
少師級
2024-04-28
陸燕萍
進(jìn)士級
2024-04-28