分布式定時(shí)任務(wù)框架選型,寫得太好了!

我們先思考下面幾個(gè)業(yè)務(wù)場(chǎng)景的解決方案: 為什么我們需要定時(shí)任務(wù) java有哪些定時(shí)任務(wù)的框架 單機(jī) 分布 分布式任務(wù)調(diào)度系統(tǒng)對(duì)比 1. 什么是分布式定時(shí)任務(wù) 2. 常見(jiàn)開源方案 4. 比較 附 定時(shí)任務(wù)的其他方案
我們先思考下面幾個(gè)業(yè)務(wù)場(chǎng)景的解決方案:
支付系統(tǒng)每天凌晨1點(diǎn)跑批,進(jìn)行一天清算,每月1號(hào)進(jìn)行上個(gè)月清算
電商整點(diǎn)搶購(gòu),商品價(jià)格8點(diǎn)整開始優(yōu)惠
12306購(gòu)票系統(tǒng),超過(guò)30分鐘沒(méi)有成功支付訂單的,進(jìn)行回收處理
商品成功發(fā)貨后,需要向客戶發(fā)送短信提醒
“類似的業(yè)務(wù)場(chǎng)景非常多,我們?cè)趺唇鉀Q?
為什么我們需要定時(shí)任務(wù)
很多業(yè)務(wù)場(chǎng)景需要我們某一特定的時(shí)刻去做某件任務(wù),定時(shí)任務(wù)解決的就是這種業(yè)務(wù)場(chǎng)景。一般來(lái)說(shuō),系統(tǒng)可以使用消息傳遞代替部分定時(shí)任務(wù),兩者有很多相似之處,可以相互替換場(chǎng)景。如,上面發(fā)貨成功發(fā)短信通知客戶的業(yè)務(wù)場(chǎng)景,我們可以在發(fā)貨成功后發(fā)送MQ消息到隊(duì)列,然后去消費(fèi)mq消息,發(fā)送短信。
但在某些場(chǎng)景下不能互換:
“a)時(shí)間驅(qū)動(dòng)/事件驅(qū)動(dòng):內(nèi)部系統(tǒng)一般可以通過(guò)時(shí)間來(lái)驅(qū)動(dòng),但涉及到外部系統(tǒng),則只能使用時(shí)間驅(qū)動(dòng)。如怕取外部網(wǎng)站價(jià)格,每小時(shí)爬一次 b)批量處理/逐條處理:批量處理堆積的數(shù)據(jù)更加高效,在不需要實(shí)時(shí)性的情況下比消息中間件更有優(yōu)勢(shì)。而且有的業(yè)務(wù)邏輯只能批量處理。如移動(dòng)每個(gè)月結(jié)算我們的話費(fèi) c)實(shí)時(shí)性/非實(shí)時(shí)性:消息中間件能夠做到實(shí)時(shí)處理數(shù)據(jù),但是有些情況下并不需要實(shí)時(shí),比如:vip升級(jí) d)系統(tǒng)內(nèi)部/系統(tǒng)解耦:定時(shí)任務(wù)調(diào)度一般是在系統(tǒng)內(nèi)部,而消息中間件可用于兩個(gè)系統(tǒng)間
java有哪些定時(shí)任務(wù)的框架
單機(jī)
timer:是一個(gè)定時(shí)器類,通過(guò)該類可以為指定的定時(shí)任務(wù)進(jìn)行配置。TimerTask類是一個(gè)定時(shí)任務(wù)類,該類實(shí)現(xiàn)了Runnable接口,缺點(diǎn)異常未檢查會(huì)中止線程 ScheduledExecutorService:相對(duì)延遲或者周期作為定時(shí)任務(wù)調(diào)度,缺點(diǎn)沒(méi)有絕對(duì)的日期或者時(shí)間 spring定時(shí)框架:配置簡(jiǎn)單功能較多,如果系統(tǒng)使用單機(jī)的話可以優(yōu)先考慮spring定時(shí)器
分布
Quartz:Java事實(shí)上的定時(shí)任務(wù)標(biāo)準(zhǔn)。但Quartz關(guān)注點(diǎn)在于定時(shí)任務(wù)而非數(shù)據(jù),并無(wú)一套根據(jù)數(shù)據(jù)處理而定制化的流程。雖然Quartz可以基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)作業(yè)的高可用,但缺少分布式并行調(diào)度的功能 TBSchedule:阿里早期開源的分布式任務(wù)調(diào)度系統(tǒng)。代碼略陳舊,使用timer而非線程池執(zhí)行任務(wù)調(diào)度。眾所周知,timer在處理異常狀況時(shí)是有缺陷的。而且TBSchedule作業(yè)類型較為單一,只能是獲取/處理數(shù)據(jù)一種模式。還有就是文檔缺失比較嚴(yán)重 elastic-job:當(dāng)當(dāng)開發(fā)的彈性分布式任務(wù)調(diào)度系統(tǒng),功能豐富強(qiáng)大,采用zookeeper實(shí)現(xiàn)分布式協(xié)調(diào),實(shí)現(xiàn)任務(wù)高可用以及分片,目前是版本2.15,并且可以支持云開發(fā) Saturn:是唯品會(huì)自主研發(fā)的分布式的定時(shí)任務(wù)的調(diào)度平臺(tái),基于當(dāng)當(dāng)?shù)膃lastic-job 版本1開發(fā),并且可以很好的部署到docker容器上。 xxl-job: 是大眾點(diǎn)評(píng)員工徐雪里于2015年發(fā)布的分布式任務(wù)調(diào)度平臺(tái),是一個(gè)輕量級(jí)分布式任務(wù)調(diào)度框架,其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡(jiǎn)單、輕量級(jí)、易擴(kuò)展。
分布式任務(wù)調(diào)度系統(tǒng)對(duì)比
1. 什么是分布式定時(shí)任務(wù)
把分散的,可靠性差的計(jì)劃任務(wù)納入統(tǒng)一的平臺(tái),并實(shí)現(xiàn)集群管理調(diào)度和分布式部署的一種定時(shí)任務(wù)的管理方式。叫做分布式定時(shí)任務(wù)。
2. 常見(jiàn)開源方案
elastic-job xxl-job quartz saturn opencron antares
elastic-job
elastic-job 是由當(dāng)當(dāng)網(wǎng)基于quartz 二次開發(fā)之后的分布式調(diào)度解決方案 , 由兩個(gè)相對(duì)獨(dú)立的子項(xiàng)目Elastic-Job-Lite和Elastic-Job-Cloud組成 。
Elastic-Job-Lite定位為輕量級(jí)無(wú)中心化解決方案,使用jar包的形式提供分布式任務(wù)的協(xié)調(diào)服務(wù)。
Elastic-Job-Cloud使用Mesos + Docker(TBD)的解決方案,額外提供資源治理、應(yīng)用分發(fā)以及進(jìn)程隔離等服務(wù)
亮點(diǎn)?:
“基于quartz 定時(shí)任務(wù)框架為基礎(chǔ)的,因此具備quartz的大部分功能
使用zookeeper做協(xié)調(diào),調(diào)度中心,更加輕量級(jí)
持任務(wù)的分片
支持彈性擴(kuò)容 , 可以水平擴(kuò)展 , 當(dāng)任務(wù)再次運(yùn)行時(shí),會(huì)檢查當(dāng)前的服務(wù)器數(shù)量,重新分片,分片結(jié)束之后才會(huì)繼續(xù)執(zhí)行任務(wù)
失效轉(zhuǎn)移,容錯(cuò)處理,當(dāng)一臺(tái)調(diào)度服務(wù)器宕機(jī)或者跟zookeeper斷開連接之后,會(huì)立即停止作業(yè),然后再去尋找其他空閑的調(diào)度服務(wù)器,來(lái)運(yùn)行剩余的任務(wù)
提供運(yùn)維界面,可以管理作業(yè)和注冊(cè)中心。
elastic-job結(jié)合了quartz非常優(yōu)秀的時(shí)間調(diào)度功能,并且利用ZooKeeper實(shí)現(xiàn)了靈活的分片策略。除此之外,還加入了大量實(shí)用的監(jiān)控和管理功能,
以及其開源社區(qū)活躍、文檔齊全、代碼優(yōu)雅等優(yōu)點(diǎn),是分布式任務(wù)調(diào)度框架的推薦選擇。
由于elastic-job-lite 不支持動(dòng)態(tài)添加作業(yè),此處僅貼上elastic-job-Cloud架構(gòu)圖
xxl-job
由個(gè)人開源的一個(gè)輕量級(jí)分布式任務(wù)調(diào)度框架 ,主要分為 調(diào)度中心和執(zhí)行器兩部分 , 調(diào)度中心在啟動(dòng)初始化的時(shí)候,會(huì)默認(rèn)生成執(zhí)行器的RPC代理
對(duì)象(http協(xié)議調(diào)用), 執(zhí)行器項(xiàng)目啟動(dòng)之后, 調(diào)度中心在觸發(fā)定時(shí)器之后通過(guò)jobHandle 來(lái)調(diào)用執(zhí)行器項(xiàng)目里面的代碼,核心功能和elastic-job差不多,同時(shí)技術(shù)文檔比較完善
系統(tǒng)架構(gòu)圖?:
quartz
quartz 的常見(jiàn)集群方案如下,通過(guò)在數(shù)據(jù)庫(kù)中配置定時(shí)器信息, 以數(shù)據(jù)庫(kù)悲觀鎖的方式達(dá)到同一個(gè)任務(wù)始終只有一個(gè)節(jié)點(diǎn)在運(yùn)行,
優(yōu)點(diǎn)?:
保證節(jié)點(diǎn)高可用 (HA), 如果某一個(gè)幾點(diǎn)掛了, 其他節(jié)點(diǎn)可以頂上
缺點(diǎn)?:
同一個(gè)任務(wù)只能有一個(gè)節(jié)點(diǎn)運(yùn)行,其他節(jié)點(diǎn)將不執(zhí)行任務(wù),性能低,資源浪費(fèi)
當(dāng)碰到大量短任務(wù)時(shí),各個(gè)節(jié)點(diǎn)頻繁的競(jìng)爭(zhēng)數(shù)據(jù)庫(kù)鎖,節(jié)點(diǎn)越多這種情況越嚴(yán)重。性能會(huì)很低下
quartz 的分布式僅解決了集群高可用的問(wèn)題,并沒(méi)有解決任務(wù)分片的問(wèn)題,不能實(shí)現(xiàn)水平擴(kuò)展
Saturn
Saturn是唯品會(huì)在github開源的一款分布式任務(wù)調(diào)度產(chǎn)品。它是基于當(dāng)當(dāng)elastic-job 1.0版本來(lái)開發(fā)的,其上完善了一些功能和添加了一些新的feature。
亮點(diǎn)?:
支持多語(yǔ)言開發(fā) python、Go、Shell、Java、Php。
管理控制臺(tái)和數(shù)據(jù)統(tǒng)計(jì)分析更加完善
缺點(diǎn)?:
技術(shù)文檔較少 , 該框架是2016年由唯品會(huì)的研發(fā)團(tuán)隊(duì)基于elastic-job開發(fā)而來(lái)
opencron
一個(gè)功能完善真正通用的linux定時(shí)任務(wù)調(diào)度定系統(tǒng),滿足多種場(chǎng)景下各種復(fù)雜的定時(shí)任務(wù)調(diào)度,同時(shí)集成了linux實(shí)時(shí)監(jiān)控,webssh,提供一個(gè)方便管理定時(shí)任務(wù)的平臺(tái)
缺點(diǎn):僅支持 kill任務(wù), 現(xiàn)場(chǎng)執(zhí)行,查詢?nèi)蝿?wù)運(yùn)行狀態(tài) 等, 主要功能是著重于任務(wù)的修改和查詢上。不能動(dòng)態(tài)的添加任務(wù)以及任務(wù)分片。
antares
優(yōu)點(diǎn)?:
一個(gè)任務(wù)僅會(huì)被服務(wù)器集群中的某個(gè)節(jié)點(diǎn)調(diào)度,調(diào)度機(jī)制基于成熟的 quartz 并行執(zhí)行 , 用戶可通過(guò)對(duì)任務(wù)預(yù)分片,有效提升任務(wù)執(zhí)行效率 失效轉(zhuǎn)移 彈性擴(kuò)容,在任務(wù)運(yùn)行時(shí),可以動(dòng)態(tài)的加機(jī)器 友好的管理控制臺(tái)
缺點(diǎn)?:
不能動(dòng)態(tài)的添加任務(wù),僅能在控制臺(tái)對(duì)任務(wù)進(jìn)行觸發(fā),暫停,刪除等操作 文檔不多,開源社區(qū)不夠活躍
系統(tǒng)架構(gòu)圖如下?:
4. 比較
此處列出了幾個(gè)代表性的開源產(chǎn)品
附 定時(shí)任務(wù)的其他方案
發(fā)貨后超過(guò)10天未收貨時(shí)系統(tǒng)自動(dòng)確認(rèn)收貨的多種實(shí)現(xiàn)方式
“每天定時(shí)半夜篩選第二天 可以自動(dòng)確認(rèn)收貨的訂單,然后第二天 每10分鐘 執(zhí)行一次確認(rèn)收貨 開銷不會(huì)太大吧 時(shí)間也相對(duì)精確
自動(dòng)確認(rèn)收貨這個(gè)狀態(tài)如果僅僅是讓客戶端看的話,等用戶下一次上線的時(shí)間,做一次運(yùn)算就可以了。
延遲和定時(shí)消息投遞
ActiveMQ提供了一種broker端消息定時(shí)調(diào)度機(jī)制。適用于:1、不希望消息馬上被broker投遞出去,而是想要消息60秒以后發(fā)給消費(fèi)者,2、想讓消息沒(méi)隔一定時(shí)間投遞一次,一共投遞指定的次數(shù) RabbitMQ可以針對(duì)Queue和Message設(shè)置 x-message-tt,來(lái)控制消息的生存時(shí)間,如果超時(shí),則消息變?yōu)閐ead letter。利用DLX,當(dāng)消息在一個(gè)隊(duì)列中變成死信后,它能被重新publish到另一個(gè)Exchange。這時(shí)候消息就可以重新被消費(fèi)。
關(guān)注不迷路
