xxl-job 任務(wù)觸發(fā)流程

官方文檔:https://www.xuxueli.com/xxl-job/


先來看下任務(wù)觸發(fā)和執(zhí)行的?完整的任務(wù)觸發(fā)執(zhí)行總體流程圖 如下:

不管是自動(dòng)觸發(fā)還是UI人工手動(dòng)觸發(fā),都是依賴于DB的,定時(shí)觸發(fā)使用了經(jīng)典的時(shí)間輪算法,掃描數(shù)據(jù)庫內(nèi)數(shù)據(jù),根據(jù)對(duì)應(yīng)線程池策略,啟動(dòng)異步線程,再根據(jù)對(duì)應(yīng)的分片和路游策略,最終決定任務(wù)的執(zhí)行人,通過xxl-rpc告知對(duì)應(yīng)的執(zhí)行器。


看著這相比大家一定在想,任務(wù)是如何自動(dòng)觸發(fā)的呢?那么就一起看看任務(wù)是如何真正觸發(fā)的,如下:



1.分布式鎖

xxl-job極有可能也是多機(jī)部署,那他是如何數(shù)據(jù)的一致性呢?剛我們提到不管是人工觸發(fā)還是自動(dòng),都是依賴于DB的,想到數(shù)據(jù)第一個(gè)就想到了鎖,那么對(duì)于數(shù)據(jù)庫而言,是天然的保證數(shù)據(jù)的一致性的,一起看一下是怎么做的

細(xì)心的小伙伴一眼就看出來了,那就是“事務(wù)”和悲觀鎖,很多人看到這會(huì)有2個(gè)疑問,一個(gè)是性能,第二個(gè)是分布式鎖為什么不是redis或是zookeeper什么的,干嘛用數(shù)據(jù)庫的,那么回到問題本身,xxl-job是什么,他是一個(gè)“定時(shí)任務(wù)”,那么定時(shí)任務(wù)對(duì)性能要求是不是要求有那么高?既然對(duì)性能要求沒那么高,mysql本身是不是就足夠了,何必在引入其他的組件呢?

2.掃描可執(zhí)行數(shù)據(jù)

方法的調(diào)用

xxl-job的dao使用mybatis實(shí)現(xiàn)的,具體sql如下

pagesize:配置定死

maxNextTime:當(dāng)前時(shí)間毫秒值+5000


3.觸發(fā)算法

拿到了距now 5秒內(nèi)的任務(wù)列表數(shù)據(jù):scheduleList,分三種情況處理:for循環(huán)遍歷scheduleList集合

(1)對(duì)到達(dá)now時(shí)間后的任務(wù):(超出now 5秒外):直接跳過不執(zhí)行; 重置trigger_next_time;

(2)對(duì)到達(dá)now時(shí)間后的任務(wù):(超出now 5秒內(nèi)):線程執(zhí)行觸發(fā)邏輯; 若任務(wù)下一次觸發(fā)時(shí)間是在5秒內(nèi), 則放到時(shí)間輪內(nèi)(Map<Integer, List<Integer>> 秒數(shù)(1-60) => 任務(wù)id列表);再 重置trigger_next_time

(3)對(duì)未到達(dá)now時(shí)間的任務(wù):直接放到時(shí)間輪內(nèi);重置trigger_next_time 。


3.時(shí)間輪算法觸發(fā)

xxl-job時(shí)間輪數(shù)據(jù)結(jié)構(gòu): Map<Integer, List<Integer>>? key是秒數(shù)(1-60)? value是任務(wù)id列表,具體結(jié)構(gòu)如下圖 :


代碼具體如下:


間輪數(shù)據(jù)結(jié)構(gòu): Map<Integer, List<Integer>>key是hash計(jì)算觸發(fā)時(shí)間獲得的秒數(shù)(1-60),value是任務(wù)id列表

入輪:掃描任務(wù)觸發(fā)時(shí) (1)本次任務(wù)處理完成,但下一次觸發(fā)時(shí)間是在5秒內(nèi)(2)本次任務(wù)未達(dá)到觸發(fā)時(shí)間? ? ?? ? ? 出輪:獲取當(dāng)前時(shí)間秒數(shù),從時(shí)間輪內(nèi)移出當(dāng)前秒數(shù)前2個(gè)秒數(shù)的任務(wù)id列表, 依次進(jìn)行觸發(fā)任務(wù);(避免處理耗時(shí)太長,跨過刻度,多向前校驗(yàn)一秒)

增加時(shí)間輪的目的是:任務(wù)過多可能會(huì)延遲,為了保障觸發(fā)時(shí)間盡可能和 任務(wù)設(shè)置的觸發(fā)時(shí)間盡量一致,把即將要觸發(fā)的任務(wù)提前放到時(shí)間輪里,每秒來觸發(fā)時(shí)間輪相應(yīng)節(jié)點(diǎn)的任務(wù)


到這xxl-job的執(zhí)行流程也大致講完了,那么說一說我對(duì)他的執(zhí)行流程的一點(diǎn)理解和可能存在的問題,首先明確一下他是一個(gè)定時(shí)任務(wù),既然是“定時(shí)”任務(wù),那么第一個(gè)想到時(shí)效性,當(dāng)一次取出的任務(wù)過多時(shí),Map的結(jié)果vaule過于龐大,那么在1秒內(nèi)極有可能是不能執(zhí)行完的,最直接的解決辦法就是“少吃多餐”,增加取得頻率降低每次取出的數(shù)目,這么做必然降低性能,這個(gè)時(shí)候就需要使用者自行斟酌了,到底是要“性能”還是要“時(shí)效性”,個(gè)人建議更加注重性能,定時(shí)任務(wù)大多數(shù)時(shí)候晚幾秒影響沒那么大,當(dāng)然具體還要看使用者的具體場景。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容