定時任務(wù)是一個常見的需求,如果只是單機部署的話, 可以直接使用springboot自帶的schedule來完成。但是在分布式系統(tǒng)中,如何確保多個節(jié)點在同一時間只有一個服務(wù)執(zhí)行定時任務(wù)?
在實際的過程中,換過幾個定時任務(wù)框架,針對使用過的框架做一個簡單的說明和分析。
框架對比和選擇
- 最開始使用的是
xxl-job,這個項目是個人開發(fā)者維護(hù)的,不過github上star還是比較多的,所以就準(zhǔn)備做個嘗試。開始使用的時候就發(fā)現(xiàn)它是一個集中管理和集中調(diào)度的模式。有一個中心節(jié)點來進(jìn)行任務(wù)分配,并且分配的方式還是通過自帶的rpc調(diào)用方式,還需要在springboot服務(wù)中部署額外的jetty服務(wù),感覺和現(xiàn)在的模式?jīng)_突太大,并且給官方提供了意見,不過被官方給否決了。后面查看了xxl-job的源碼,感覺代碼質(zhì)量很一般,所以最終放棄了這個框架。 - 然后引入了
elastic-job,算是當(dāng)當(dāng)開源的框架,代碼質(zhì)量明顯比xxl-job有了提升,他沒有中心節(jié)點,是通過zk來實現(xiàn)了分布式的調(diào)度,支持的模式種類比較多,不過常用的只有一種模式,就是在多個節(jié)點中選擇一個節(jié)點進(jìn)行調(diào)度執(zhí)行,算是比較完美的解決了定時調(diào)度的問題。但是隨著springboot和springcloud的基礎(chǔ)框架不停的迭代和升級,發(fā)現(xiàn)elastic-job已經(jīng)沒有更新,并且社區(qū)逐漸不活躍,作者也把主要的精力轉(zhuǎn)移到另外的項目里面,這一塊的維護(hù)力度明顯下降。所以也打算選擇新的框架來替換elastic-job - 本著項目輕量和簡潔的目的,后面發(fā)現(xiàn)了
shedlock這個項目,僅僅是利用底層存儲(mysql、redis等)作為分布式鎖。通過自定義的注解,并且結(jié)合springboot原生的schedule來完成分布式調(diào)度的執(zhí)行的功能。他設(shè)計目標(biāo)非常明確,并且代碼十分簡單,代碼質(zhì)量也不錯,底層的依賴也特別少,并且也在持續(xù)更新。所以最后用shedlock替換了elastic-job,目前使用得也十分穩(wěn)定。不過shedlock由于功能很基礎(chǔ),后面自己通過springboot的endpoint來進(jìn)行了功能的擴展,實現(xiàn)了定時任務(wù)的觸發(fā)、停止、改變調(diào)度周期等常規(guī)需求,來彌補一些業(yè)務(wù)上的需求。最終減少了基礎(chǔ)組件依賴的同時高效的完成了目標(biāo)。