上一篇,我們介紹瞭如何使用Elastic Job實現定時任務。解決了使用@Scheduled
來實現時候存在的競爭問題,同時也實現了定時任務的高可用執行。
然而,還有一類問題是我們在做定時任務時候容易出現的,就是任務執行速度時間過長;同時,為了實現定時任務的高可用,還啟動了很多工例項,但每個任務執行時候就一個例項在跑,資源利用率不高。
所以,接下來我們就來繼續介紹,使用Elastic Job的分片配置,來為任務執行加加速,資源利用抬抬高的目標!
動手試試
建議直接下載文末倉庫中的chapter7-2
工程,然後在這個基礎上進行修改。當然,如果你對如何使用Elastic Job還不輸入,那麼先前往上一篇做個知識鋪墊,再繼續下面的內容!
第一步:建立一個分片執行的任務
@Slf4j
@Service
public class MyShardingJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
switch (context.getShardingItem()) {
case 0:
log.info("分片1:執行任務");
break;
case 1:
log.info("分片2:執行任務");
break;
case 2:
log.info("分片3:執行任務");
break;
}
}
}
這裡通過switch
來判斷當前任務上下文的sharding-item值來執行不同的分片任務。sharding-item的值取決於後面將要配置的分片總數,但注意是從0開始計數的。 這裡僅採用了日誌列印的方式,來展示分片效果,真正實現業務邏輯的時候,一定記得根據分片數量對執行任務也要做分片操作的設計。比如:你可以根據批量任務的id求摩的方式來區分不同分片處理不同的資料,以避免重複執行而出現問題。
第二步:在配置檔案中,設定配置任務的實現類、執行表示式、以及將要重要測試的分片總數引數
elasticjob.jobs.my-sharding-job.elastic-job-class=com.didispace.chapter73.MyShardingJob
elasticjob.jobs.my-sharding-job.cron=0/5 * * * * ?
elasticjob.jobs.my-sharding-job.sharding-total-count=3
這裡設定為3,所以任務會被分為3個分片,每個分片對應第一步中一個switch的分支。
執行與測試
單例項執行
在完成了上面的程式碼之後,嘗試啟動上面實現的第一個例項。
此時,我們可以看到,每間隔5秒,這個例項會列印這樣的日誌:
2021-07-21 17:42:00.122 INFO 63478 --- [ main] .s.b.j.ScheduleJobBootstrapStartupRunner : Starting ElasticJob Bootstrap.
2021-07-21 17:42:00.126 INFO 63478 --- [ main] org.quartz.core.QuartzScheduler : Scheduler my-sharding-job_$_NON_CLUSTERED started.
2021-07-21 17:42:00.126 INFO 63478 --- [ main] .s.b.j.ScheduleJobBootstrapStartupRunner : ElasticJob Bootstrap started.
2021-07-21 17:42:05.254 INFO 63478 --- [-sharding-job-1] com.didispace.chapter73.MyShardingJob : 分片1:執行任務
2021-07-21 17:42:05.254 INFO 63478 --- [-sharding-job-3] com.didispace.chapter73.MyShardingJob : 分片3:執行任務
2021-07-21 17:42:05.254 INFO 63478 --- [-sharding-job-2] com.didispace.chapter73.MyShardingJob : 分片2:執行任務
2021-07-21 17:42:10.011 INFO 63478 --- [-sharding-job-4] com.didispace.chapter73.MyShardingJob : 分片1:執行任務
2021-07-21 17:42:10.011 INFO 63478 --- [-sharding-job-5] com.didispace.chapter73.MyShardingJob : 分片2:執行任務
2021-07-21 17:42:10.011 INFO 63478 --- [-sharding-job-6] com.didispace.chapter73.MyShardingJob : 分片3:執行任務
每次任務都被拆分成了3個分片任務,就如我上文中所說的,每個分片對應一個switch的分支。由於當前情況下,我們只啟動了一個例項,所以3個分片任務都被分配到了這個唯一的例項上。
雙例項執行
接下來,我們再啟動一個例項(注意使用-Dserver.port來改變不同的埠,不然本地會啟動不成功)。此時,兩個例項的日誌出現了變化:
例項1的日誌:
2021-07-21 17:44:50.190 INFO 63478 --- [ng-job_Worker-1] com.didispace.chapter73.MyShardingJob : 分片2:執行任務
2021-07-21 17:44:55.007 INFO 63478 --- [ng-job_Worker-1] com.didispace.chapter73.MyShardingJob : 分片2:執行任務
2021-07-21 17:45:00.010 INFO 63478 --- [ng-job_Worker-1] com.didispace.chapter73.MyShardingJob : 分片2:執行任務
例項2的日誌:
2021-07-21 17:44:50.272 INFO 63484 --- [-sharding-job-1] com.didispace.chapter73.MyShardingJob : 分片1:執行任務
2021-07-21 17:44:50.273 INFO 63484 --- [-sharding-job-2] com.didispace.chapter73.MyShardingJob : 分片3:執行任務
2021-07-21 17:44:55.009 INFO 63484 --- [-sharding-job-3] com.didispace.chapter73.MyShardingJob : 分片1:執行任務
2021-07-21 17:44:55.009 INFO 63484 --- [-sharding-job-4] com.didispace.chapter73.MyShardingJob : 分片3:執行任務
隨著例項數量的增加,可以看到分片的分配發生了變化。這也就意味著,當一個任務開始執行的時候,兩個任務執行例項都被利用了起來,這樣我們的任務執行和資源利用的效率就可以得到優化。
你也可以嘗試再繼續啟動例項和關閉例項來觀察任務的動態分配,怎麼樣?這樣寫定時任務是不是方便多了? 一定記得自己動手寫一寫,這樣體會更深哦!如果碰到問題,可以拉取文末的程式碼示例對比一下是否有地方配置不一樣。下一篇,我們還將繼續介紹關於定時任務的一些高階內容。
本系列教程《Spring Boot 2.x基礎教程》點選直達!,歡迎收藏與轉發!如果學習過程中如遇困難?可以加入我們Spring技術交流群,參與交流與討論,更好的學習與進步!
程式碼示例
本文的完整工程可以檢視下面倉庫中的chapter7-3
目錄:
- Github:https://github.com/dyc87112/SpringBoot-Learning/
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/
如果您覺得本文不錯,歡迎Star
支援,您的關注是我堅持的動力!
歡迎關注我的公眾號:程式猿DD,分享外面看不到的乾貨與思考!