Spring Boot 2.x基礎(chǔ)教程:使用Elastic Job的分片配置

上一篇,我們介紹了如何使用Elastic Job實(shí)現(xiàn)定時(shí)任務(wù)(https://blog.didispace.com/spring-boot-learning-2-7-2/)。解決了使用@Scheduled來實(shí)現(xiàn)時(shí)候存在的競爭問題,同時(shí)也實(shí)現(xiàn)了定時(shí)任務(wù)的高可用執(zhí)行。
然而,還有一類問題是我們在做定時(shí)任務(wù)時(shí)候容易出現(xiàn)的,就是任務(wù)執(zhí)行速度時(shí)間過長;同時(shí),為了實(shí)現(xiàn)定時(shí)任務(wù)的高可用,還啟動(dòng)了很多任務(wù)實(shí)例,但每個(gè)任務(wù)執(zhí)行時(shí)候就一個(gè)實(shí)例在跑,資源利用率不高。
所以,接下來我們就來繼續(xù)介紹,使用Elastic Job的分片配置,來為任務(wù)執(zhí)行加加速,資源利用抬抬高的目標(biāo)!
動(dòng)手試試
建議直接下載文末倉庫中的chapter7-2工程,然后在這個(gè)基礎(chǔ)上進(jìn)行修改。當(dāng)然,如果你對如何使用Elastic Job還不輸入,那么先前往上一篇做個(gè)知識(shí)鋪墊,再繼續(xù)下面的內(nèi)容!
第一步:創(chuàng)建一個(gè)分片執(zhí)行的任務(wù)
@Slf4j
@Service
public class MyShardingJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
switch (context.getShardingItem()) {
case 0:
log.info("分片1:執(zhí)行任務(wù)");
break;
case 1:
log.info("分片2:執(zhí)行任務(wù)");
break;
case 2:
log.info("分片3:執(zhí)行任務(wù)");
break;
}
}
}
這里通過switch來判斷當(dāng)前任務(wù)上下文的sharding-item值來執(zhí)行不同的分片任務(wù)。sharding-item的值取決于后面將要配置的分片總數(shù),但注意是從0開始計(jì)數(shù)的。這里僅采用了日志打印的方式,來展示分片效果,真正實(shí)現(xiàn)業(yè)務(wù)邏輯的時(shí)候,一定記得根據(jù)分片數(shù)量對執(zhí)行任務(wù)也要做分片操作的設(shè)計(jì)。比如:你可以根據(jù)批量任務(wù)的id求摩的方式來區(qū)分不同分片處理不同的數(shù)據(jù),以避免又重復(fù)執(zhí)行而出現(xiàn)問題。
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
這里設(shè)置為3,所以任務(wù)會(huì)被分為3個(gè)分片,每個(gè)分片對應(yīng)第一步中一個(gè)switch的分支。
運(yùn)行與測試
單實(shí)例運(yùn)行
在完成了上面的代碼之后,嘗試啟動(dòng)上面實(shí)現(xiàn)的第一個(gè)實(shí)例。
此時(shí),我們可以看到,每間隔5秒,這個(gè)實(shí)例會(huì)打印這樣的日志:
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:執(zhí)行任務(wù)
2021-07-21 17:42:05.254 INFO 63478 --- [-sharding-job-3] com.didispace.chapter73.MyShardingJob : 分片3:執(zhí)行任務(wù)
2021-07-21 17:42:05.254 INFO 63478 --- [-sharding-job-2] com.didispace.chapter73.MyShardingJob : 分片2:執(zhí)行任務(wù)
2021-07-21 17:42:10.011 INFO 63478 --- [-sharding-job-4] com.didispace.chapter73.MyShardingJob : 分片1:執(zhí)行任務(wù)
2021-07-21 17:42:10.011 INFO 63478 --- [-sharding-job-5] com.didispace.chapter73.MyShardingJob : 分片2:執(zhí)行任務(wù)
2021-07-21 17:42:10.011 INFO 63478 --- [-sharding-job-6] com.didispace.chapter73.MyShardingJob : 分片3:執(zhí)行任務(wù)
每次任務(wù)都被拆分成了3個(gè)分片任務(wù),就如我上文中所說的,每個(gè)分片對應(yīng)一個(gè)switch的分支。由于當(dāng)前情況下,我們只啟動(dòng)了一個(gè)實(shí)例,所以3個(gè)分片任務(wù)都被分配到了這個(gè)唯一的實(shí)例上。
雙實(shí)例運(yùn)行
接下來,我們再啟動(dòng)一個(gè)實(shí)例(注意使用-Dserver.port來改變不同的端口,不然本地會(huì)啟動(dòng)不成功)。此時(shí),兩個(gè)實(shí)例的日志出現(xiàn)了變化:
實(shí)例1的日志:
2021-07-21 17:44:50.190 INFO 63478 --- [ng-job_Worker-1] com.didispace.chapter73.MyShardingJob : 分片2:執(zhí)行任務(wù)
2021-07-21 17:44:55.007 INFO 63478 --- [ng-job_Worker-1] com.didispace.chapter73.MyShardingJob : 分片2:執(zhí)行任務(wù)
2021-07-21 17:45:00.010 INFO 63478 --- [ng-job_Worker-1] com.didispace.chapter73.MyShardingJob : 分片2:執(zhí)行任務(wù)
實(shí)例2的日志:
2021-07-21 17:44:50.272 INFO 63484 --- [-sharding-job-1] com.didispace.chapter73.MyShardingJob : 分片1:執(zhí)行任務(wù)
2021-07-21 17:44:50.273 INFO 63484 --- [-sharding-job-2] com.didispace.chapter73.MyShardingJob : 分片3:執(zhí)行任務(wù)
2021-07-21 17:44:55.009 INFO 63484 --- [-sharding-job-3] com.didispace.chapter73.MyShardingJob : 分片1:執(zhí)行任務(wù)
2021-07-21 17:44:55.009 INFO 63484 --- [-sharding-job-4] com.didispace.chapter73.MyShardingJob : 分片3:執(zhí)行任務(wù)
隨著實(shí)例數(shù)量的增加,可以看到分片的分配發(fā)生了變化。這也就意味著,當(dāng)一個(gè)任務(wù)開始執(zhí)行的時(shí)候,兩個(gè)任務(wù)執(zhí)行實(shí)例都被利用了起來,這樣我們的任務(wù)執(zhí)行和資源利用的效率就可以得到優(yōu)化。
你也可以嘗試再繼續(xù)啟動(dòng)實(shí)例和關(guān)閉實(shí)例來觀察任務(wù)的動(dòng)態(tài)分配,怎么樣?這樣寫定時(shí)任務(wù)是不是方便多了?一定記得自己動(dòng)手寫一寫,這樣體會(huì)更深哦!如果碰到問題,可以拉取文末的代碼示例對比一下是否有地方配置不一樣。下一篇,我們還將繼續(xù)介紹關(guān)于定時(shí)任務(wù)的一些高級(jí)內(nèi)容。關(guān)注我,收藏本系列教程《Spring Boot 2.x基礎(chǔ)教程》(http://blog.didispace.com/spring-boot-learning-2x/)。
如果學(xué)習(xí)過程中如遇困難?可以加入我們Spring技術(shù)交流群(https://blog.didispace.com/join-group-spring/index.html),參與交流與討論,更好的學(xué)習(xí)與進(jìn)步!
代碼示例
本文的完整工程可以查看下面?zhèn)}庫中的chapter7-3目錄:
Github:https://github.com/dyc87112/SpringBoot-Learning/tree/master/2.x Gitee:https://gitee.com/didispace/SpringBoot-Learning/tree/master/2.x
如果您覺得本文不錯(cuò),歡迎Star支持,您的關(guān)注是我堅(jiān)持的動(dòng)力!
往期推薦
關(guān)注我回復(fù)「加群」,加入Spring技術(shù)交流群
