鑒于平臺定時任務(wù)執(zhí)行缺陷:
- 占用線程資源嚴(yán)重:嚴(yán)重依賴于大量的線程池(一般)
- 執(zhí)行延時操作宇弛,直接選用delay線程方案九默,會導(dǎo)致大量線程阻塞(嚴(yán)重)
- 當(dāng)需掃描的數(shù)據(jù)量很大時,每秒執(zhí)行不完全脱拼,會導(dǎo)致自動化不執(zhí)行或者重復(fù)執(zhí)行步咪,可靠性低(一般)
- 控制中心和執(zhí)行引擎沒有完全分離出來节视,代碼邏輯復(fù)雜拳锚,難以定位問題(一般) 需要選擇一款優(yōu)秀的分布式任務(wù)調(diào)度組件。
目前國內(nèi)常見的分布式定時框架:
Elastic-Job
ddframe中dd-job的作業(yè)模塊中分離出來的分布式彈性作業(yè)框架寻行。去掉了和dd-job中的監(jiān)控和ddframe接入規(guī)范部分霍掺。該項目基于成熟的開源產(chǎn)品Quartz和Zookeeper及其客戶端Curator進行二次開發(fā)。
- 優(yōu)點:比較成熟拌蜘,重量級的分布式定時任務(wù)框架 杆烁,并發(fā)量高
- 缺點:依賴 Zookeeper及其它組件,改造困難简卧,上手難度高兔魂,且部分特性不支持,目前github已沒有人員維護
xxl-job
XXL-JOB是一個輕量級分布式任務(wù)調(diào)度平臺举娩,其核心設(shè)計目標(biāo)是開發(fā)迅速析校、學(xué)習(xí)簡單、輕量級晓铆、易擴展∩琢迹現(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用骄噪。
- 優(yōu)點:開發(fā)迅速、學(xué)習(xí)簡單蠢箩、輕量級链蕊、易擴展,目前用戶比Elastic-Job略高谬泌,文檔全面滔韵,且一直在更新版本,有問題可以聯(lián)系開源作者
- 缺點:并發(fā)量沒有Elastic-Job高掌实。但最新的穩(wěn)定版本已支持調(diào)度全異步處理
spring單節(jié)點@Scheduled調(diào)度組件
- 優(yōu)點:支持spring陪蜻,使用簡單。
- 缺點:
1 節(jié)點不能水平擴展 , 多個節(jié)點之間任務(wù)是無感知的 , 會造成多余的資源浪費 , 一些調(diào)度任務(wù)多節(jié)點并行執(zhí)行還可能導(dǎo)致資源爭用造成一些異常問題
2 管理方式不靈活 , 一些特定場景下不能及時主動進行觸發(fā)或者開關(guān)
3 調(diào)度任務(wù)的監(jiān)控功能需要自己實現(xiàn) , 調(diào)度體系大了 , 難以做到比較全面的管理贱鼻、監(jiān)控 , 并且此功能需要投入額外的開發(fā)成本
quartz宴卖,TBSchedule等
不支持分片或者無人維護無文檔,不考慮
引入定時框架后解決的問題
1.由于開源定時任務(wù)框架經(jīng)歷了很多的場景考驗邻悬,對于線程池分配方便會把控較好症昏,不存在濫用情況「阜幔可以完全取消掉ifttt-trigger肝谭,ifttt-handler中的常駐進程,避免產(chǎn)生線程資源耗盡等狀況
2.延時操作目前考慮將一個含delay定時任務(wù)拆分成多個任務(wù),解決線程阻塞問題攘烛。
3.去除掃描操作魏滚,由控制中心統(tǒng)一調(diào)度,由被動的輪詢改為主動的中心調(diào)度坟漱,可靠性百分百鼠次。
4.開源框架調(diào)度中心和執(zhí)行器是完全隔離的,我們只需要復(fù)寫例如執(zhí)行器等靖秩,不用考慮任務(wù)調(diào)度過程须眷。簡化定時任務(wù)執(zhí)行邏輯。
3沟突、xxljob介紹
xxl-job官方介紹([http://www.xuxueli.com/xxl-job/#]
概述
XXL-JOB是一個輕量級分布式任務(wù)調(diào)度平臺花颗,其核心設(shè)計目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡單惠拭、輕量級扩劝、易擴展。現(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線职辅,開箱即用棒呛。
-
示例圖:
image.png
特性
簡單:支持通過Web頁面對任務(wù)進行CRUD操作,操作簡單域携,一分鐘上手簇秒;
動態(tài):支持動態(tài)修改任務(wù)狀態(tài)、啟動/停止任務(wù)秀鞭,以及終止運行中任務(wù)趋观,即時生效;
調(diào)度中心HA(中心式):調(diào)度采用中心式設(shè)計锋边,“調(diào)度中心”基于集群Quartz實現(xiàn)并支持集群部署皱坛,可保證調(diào)度中心HA;
執(zhí)行器HA(分布式):任務(wù)分布式執(zhí)行豆巨,任務(wù)"執(zhí)行器"支持集群部署剩辟,可保證任務(wù)執(zhí)行HA;
注冊中心: 執(zhí)行器會周期性自動注冊任務(wù), 調(diào)度中心將會自動發(fā)現(xiàn)注冊的任務(wù)并觸發(fā)執(zhí)行往扔。同時贩猎,也支持手動錄入執(zhí)行器地址;
彈性擴容縮容:一旦有新執(zhí)行器機器上線或者下線瓤球,下次調(diào)度時將會重新分配任務(wù)融欧;
路由策略:執(zhí)行器集群部署時提供豐富的路由策略,包括:第一個卦羡、最后一個噪馏、輪詢麦到、隨機、一致性HASH欠肾、最不經(jīng)常使用瓶颠、最近最久未使用、故障轉(zhuǎn)移刺桃、忙碌轉(zhuǎn)移等粹淋;
故障轉(zhuǎn)移:任務(wù)路由策略選擇"故障轉(zhuǎn)移"情況下,如果執(zhí)行器集群中某一臺機器故障瑟慈,將會自動Failover切換到一臺正常的執(zhí)行器發(fā)送調(diào)度請求桃移。
阻塞處理策略:調(diào)度過于密集執(zhí)行器來不及處理時的處理策略,策略包括:單機串行(默認(rèn))葛碧、丟棄后續(xù)調(diào)度借杰、覆蓋之前調(diào)度;
任務(wù)超時控制:支持自定義任務(wù)超時時間进泼,任務(wù)運行超時將會主動中斷任務(wù)蔗衡;
任務(wù)失敗重試:支持自定義任務(wù)失敗重試次數(shù),當(dāng)任務(wù)失敗時將會按照預(yù)設(shè)的失敗重試次數(shù)主動進行重試乳绕;其中分片任務(wù)支持分片粒度的失敗重試绞惦;
任務(wù)失敗告警;默認(rèn)提供郵件方式失敗告警洋措,同時預(yù)留擴展接口济蝉,可方便的擴展短信、釘釘?shù)雀婢绞剑?/p>
分片廣播任務(wù):執(zhí)行器集群部署時菠发,任務(wù)路由策略選擇"分片廣播"情況下堆生,一次任務(wù)調(diào)度將會廣播觸發(fā)集群中所有執(zhí)行器執(zhí)行一次任務(wù),可根據(jù)分片參數(shù)開發(fā)分片任務(wù)雷酪;
動態(tài)分片:分片廣播任務(wù)以執(zhí)行器為維度進行分片,支持動態(tài)擴容執(zhí)行器集群從而動態(tài)增加分片數(shù)量涝婉,協(xié)同進行業(yè)務(wù)處理哥力;在進行大數(shù)據(jù)量業(yè)務(wù)操作時可顯著提升任務(wù)處理能力和速度。
事件觸發(fā):除了"Cron方式"和"任務(wù)依賴方式"觸發(fā)任務(wù)執(zhí)行之外墩弯,支持基于事件的觸發(fā)任務(wù)方式吩跋。調(diào)度中心提供觸發(fā)任務(wù)單次執(zhí)行的API服務(wù),可根據(jù)業(yè)務(wù)事件靈活觸發(fā)渔工。
任務(wù)進度監(jiān)控:支持實時監(jiān)控任務(wù)進度锌钮;
Rolling實時日志:支持在線查看調(diào)度結(jié)果,并且支持以Rolling方式實時查看執(zhí)行器輸出的完整的執(zhí)行日志引矩;
GLUE:提供Web IDE梁丘,支持在線開發(fā)任務(wù)邏輯代碼侵浸,動態(tài)發(fā)布,實時編譯生效氛谜,省略部署上線的過程掏觉。支持30個版本的歷史版本回溯。
腳本任務(wù):支持以GLUE模式開發(fā)和運行腳本任務(wù)值漫,包括Shell澳腹、Python、NodeJS杨何、PHP酱塔、PowerShell等類型腳本;
命令行任務(wù):原生提供通用命令行任務(wù)Handler(Bean任務(wù),"CommandJobHandler")危虱;業(yè)務(wù)方只需要提供命令行即可羊娃;
任務(wù)依賴:支持配置子任務(wù)依賴,當(dāng)父任務(wù)執(zhí)行結(jié)束且執(zhí)行成功后將會主動觸發(fā)一次子任務(wù)的執(zhí)行, 多個子任務(wù)用逗號分隔槽地;
一致性:“調(diào)度中心”通過DB鎖保證集群分布式調(diào)度的一致性, 一次任務(wù)調(diào)度只會觸發(fā)一次執(zhí)行迁沫;
自定義任務(wù)參數(shù):支持在線配置調(diào)度任務(wù)入?yún)ⅲ磿r生效捌蚊;
調(diào)度線程池:調(diào)度系統(tǒng)多線程觸發(fā)調(diào)度運行集畅,確保調(diào)度精確執(zhí)行,不被堵塞缅糟;
數(shù)據(jù)加密:調(diào)度中心和執(zhí)行器之間的通訊進行數(shù)據(jù)加密挺智,提升調(diào)度信息安全性;
郵件報警:任務(wù)失敗時支持郵件報警窗宦,支持配置多郵件地址群發(fā)報警郵件赦颇;
推送maven中央倉庫: 將會把最新穩(wěn)定版推送到maven中央倉庫, 方便用戶接入和使用;
運行報表:支持實時查看運行數(shù)據(jù),如任務(wù)數(shù)量赴涵、調(diào)度次數(shù)媒怯、執(zhí)行器數(shù)量等;以及調(diào)度報表髓窜,如調(diào)度日期分布圖扇苞,調(diào)度成功分布圖等;
全異步:任務(wù)調(diào)度流程全異步化設(shè)計實現(xiàn)寄纵,如異步調(diào)度鳖敷、異步運行、異步回調(diào)等程拭,有效對密集調(diào)度進行流量削峰定踱,理論上支持任意時長任務(wù)的運行;
跨平臺:原生提供通用HTTP任務(wù)Handler(Bean任務(wù)恃鞋,"HttpJobHandler")崖媚;業(yè)務(wù)方只需要提供HTTP鏈接即可亦歉,不限制語言、平臺至扰;
國際化:調(diào)度中心支持國際化設(shè)置鳍徽,提供中文、英文兩種可選語言敢课,默認(rèn)為中文阶祭;
容器化:提供官方docker鏡像,并實時更新推送dockerhub直秆,進一步實現(xiàn)產(chǎn)品開箱即用濒募;
線程池隔離:調(diào)度線程池進行隔離拆分,慢任務(wù)自動降級進入"Slow"線程池圾结,避免耗盡調(diào)度線程瑰剃,提高系統(tǒng)穩(wěn)定性;筝野;
4晌姚、xlljob 使用
4.1、server服務(wù)調(diào)度端
- 部署方式:
- 訪問路徑: [ip]:[port]/retail_xxljob
- 默認(rèn)賬密: admin / 123456
4.2歇竟、client業(yè)務(wù)端
maven 依賴配置:
<!--netty模塊依賴請放置在<dependencys>里最前面(第一個),避免maven使用其他低版本netty造成問題-->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${com.xuxueli.xxl-job-core}</version>
</dependency>
bean配置類
xxl 配置類:(復(fù)制即可 , 目標(biāo)模塊有就不需要再配置)
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appName;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppName(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
配置文件yaml
- application.yml配置文件(只需要修改 appname挥唠、port 配置):
注: port 端口號設(shè)置請按 [新零售整體文檔] -> [開發(fā)配置總匯] -> [各模塊端口登記] 中的約定進行注冊、使用
xxl:
job:
### 執(zhí)行器通訊TOKEN [選填]:非空時啟用焕议;
accessToken: ''
executor:
### 執(zhí)行器AppName [選填]:執(zhí)行器心跳注冊分組依據(jù)宝磨;為空則關(guān)閉自動注冊
appname: lumi-retail-xxljob-pc
### 執(zhí)行器IP [選填]:默認(rèn)為空表示自動獲取IP,多網(wǎng)卡時可手動設(shè)置指定IP盅安,該IP不會綁定Host僅作為通訊實用唤锉;地址信息用于 "執(zhí)行器注冊" 和 "調(diào)度中心請求并觸發(fā)任務(wù)";
ip: ''
### 執(zhí)行器運行日志文件存儲磁盤路徑 [選填] :需要對該路徑擁有讀寫權(quán)限别瞭;為空則使用默認(rèn)路徑窿祥;
logpath: ${user.home}/data/logs/xxljob
### 執(zhí)行器日志保存天數(shù) [選填] :值大于3時生效,啟用執(zhí)行器Log文件定期清理功能蝙寨,否則不生效壁肋;
logretentiondays: 7
### 執(zhí)行器端口號 [選填]:小于等于0則自動獲取籽慢;默認(rèn)端口為9999,單機部署多個執(zhí)行器時猫胁,注意要配置不同執(zhí)行器端口箱亿;
port: 9402
- application-dev.yml配置文件(只需要修改 addresses中的ip)
注: ip 即為 server 服務(wù)調(diào)度端設(shè)置的 Ip
xxl:
job:
admin:
### 調(diào)度中心部署跟地址 [選填]:如調(diào)度中心集群部署存在多個地址則用逗號分隔。執(zhí)行器將會使用該地址進行"執(zhí)行器心跳注冊"和"任務(wù)結(jié)果回調(diào)"弃秆;為空則關(guān)閉自動注冊届惋;
addresses: http://10.0.14.152:9400/retail_xxljob
業(yè)務(wù)定時任務(wù)類(根據(jù)業(yè)務(wù)定制)
注: 以下僅為 demo 示例
@Slf4j
//此值配置即為下圖使用使用的JobHandler任務(wù)名
@JobHandler(value = "afterAlarmRelieveJob")
@Component
public class AfterAlarmRelieveJobHandler extends IJobHandler {
@Autowired
AlarmRecordService alarmRecordService;
@Override
public ReturnT<String> execute(String param) throws Exception {
log.info("售后工單預(yù)警解除任務(wù)開始...");
long start = System.currentTimeMillis();
alarmRecordService.afterAlarmRelieve();
log.info("售后工單預(yù)警解除任務(wù)完成髓帽,共耗時:" + (System.currentTimeMillis() - start) / 1000 + "s");
return SUCCESS;
}
}
4.3、調(diào)度模塊管理頁面配置
訪問
根據(jù)需要分別啟動對應(yīng)環(huán)境的 xll 模塊( lumi_retail_xxljob_admin )
調(diào)度管理模塊訪問頁面: [ip]:9300/retail_xxljob
賬密: admin / 123456
效果如下:
新增執(zhí)行器
注: 一個模塊只需配置一次即可
執(zhí)行器 , 顧名思義即為執(zhí)行調(diào)度任務(wù)的執(zhí)行器,示例如下
appname: 即為 client業(yè)務(wù)端yaml 配置文件中對應(yīng)的 appname
機器地址: 即 client 端的地址,多個以,號分隔(英文逗號)
新增調(diào)度任務(wù)
- 路由策略: 建議默認(rèn)為輪詢
- JobHandler: 即為上文 [client業(yè)務(wù)端] -> [業(yè)務(wù)定時任務(wù)類] 注解中@JobHandler(value = "afterAlarmRelieveJob")的value值
- cron: 相應(yīng)的執(zhí)行策略
- 任務(wù)描述脑豹、負(fù)責(zé)人: 填寫相關(guān)描述郑藏、人員
任務(wù)管理頁面開啟、執(zhí)行
新增完即可配置定時執(zhí)行/主動執(zhí)行等:
按鈕解釋:
[啟動/停止]: 是針對 cron 是否開啟/停止的開關(guān)控制 , 開啟則會根據(jù) cron 規(guī)則去操作執(zhí)行相應(yīng)業(yè)務(wù)邏輯
[執(zhí)行]: 是否主動觸發(fā) , 立即執(zhí)行此任務(wù)邏輯
注: 點擊執(zhí)行按鈕后 , 會出現(xiàn)如下圖示框 , 無須關(guān)注參數(shù)輸入框 , 直接點保存(即執(zhí)行).
- 調(diào)度任務(wù)查看/監(jiān)控等: