<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Boot 2.x基礎(chǔ)教程:使用Elastic Job實(shí)現(xiàn)定時(shí)任務(wù)

          共 8961字,需瀏覽 18分鐘

           ·

          2021-07-27 02:58

          上一篇,我們介紹了如何使用Spring Boot自帶的@Scheduled注解實(shí)現(xiàn)定時(shí)任務(wù)(https://blog.didispace.com/spring-boot-learning-2-7-1/)。文末也提及了這種方式的局限性。當(dāng)在集群環(huán)境下的時(shí)候,如果任務(wù)的執(zhí)行或操作依賴一些共享資源的話,就會(huì)存在競(jìng)爭(zhēng)關(guān)系。如果不引入分布式鎖等機(jī)制來(lái)做調(diào)度的話,就可能出現(xiàn)預(yù)料之外的執(zhí)行結(jié)果。所以,@Scheduled注解更偏向于使用在單實(shí)例自身維護(hù)相關(guān)的一些定時(shí)任務(wù)上會(huì)更為合理一些,比如:定時(shí)清理服務(wù)實(shí)例某個(gè)目錄下的文件、定時(shí)上傳本實(shí)例的一些統(tǒng)計(jì)數(shù)據(jù)等。

          那么,在實(shí)際實(shí)現(xiàn)業(yè)務(wù)邏輯的時(shí)候,沒(méi)有更好的定時(shí)任務(wù)方案呢?今天我們就來(lái)介紹一個(gè)老牌的分布式定時(shí)任務(wù)框架,在Spring Boot下的使用案例。

          Elastic Job

          Elastic Job的前生是當(dāng)當(dāng)開源的一款分布式任務(wù)調(diào)度框架,而目前已經(jīng)加入到了Apache基金會(huì)。

          該項(xiàng)目下有兩個(gè)分支:ElasticJob-Lite和ElasticJob-Cloud。ElasticJob-Lite是一個(gè)輕量級(jí)的任務(wù)管理方案,本文接下來(lái)的案例就用這個(gè)來(lái)實(shí)現(xiàn)。而 ElasticJob-Cloud則相對(duì)重一些,因?yàn)樗褂萌萜鱽?lái)管理任務(wù)和隔離資源。

          更多關(guān)于ElasticJob的介紹,您也可以點(diǎn)擊這里直達(dá)官方網(wǎng)站(https://shardingsphere.apache.org/elasticjob/)了解更多信息。

          動(dòng)手試試

          說(shuō)那么多,一起動(dòng)手試試吧!

          第一步:創(chuàng)建一個(gè)最基礎(chǔ)的Spring Boot項(xiàng)目,如果還不會(huì)?那么看看這篇快速入門(https://blog.didispace.com/spring-boot-learning-21-1-1/)。

          第二步pom.xml中添加elasticjob-lite的starter

          <dependencies>
              <dependency>
                  <groupId>org.apache.shardingsphere.elasticjob</groupId>
                  <artifactId>elasticjob-lite-spring-boot-starter</artifactId>
                  <version>3.0.0</version>
              </dependency>

              // ...
          </dependencies>

          第三步:創(chuàng)建一個(gè)簡(jiǎn)單任務(wù)

          @Slf4j
          @Service
          public class MySimpleJob implements SimpleJob {

              @Override
              public void execute(ShardingContext context) {
                  log.info("MySimpleJob start : didispace.com {}", System.currentTimeMillis());
              }

          }

          第四步:編輯配置文件

          elasticjob.reg-center.server-lists=localhost:2181
          elasticjob.reg-center.namespace=didispace

          elasticjob.jobs.my-simple-job.elastic-job-class=com.didispace.chapter72.MySimpleJob
          elasticjob.jobs.my-simple-job.cron=0/5 * * * * ?
          elasticjob.jobs.my-simple-job.sharding-total-count=1

          這里主要有兩個(gè)部分:

          第一部分:elasticjob.reg-center開頭的,主要配置elastic job的注冊(cè)中心和namespace

          第二部分:任務(wù)配置,以elasticjob.jobs開頭,這里的my-simple-job是任務(wù)的名稱,根據(jù)你的喜好命名即可,但不要重復(fù)。任務(wù)的下的配置elastic-job-class是任務(wù)的實(shí)現(xiàn)類,cron是執(zhí)行規(guī)則表達(dá)式,sharding-total-count是任務(wù)分片的總數(shù)。我們可以通過(guò)這個(gè)參數(shù)來(lái)把任務(wù)切分,實(shí)現(xiàn)并行處理。這里先設(shè)置為1,后面我們另外講分片的使用。

          運(yùn)行與測(cè)試

          完成了上面所有操作時(shí)候,我們可以嘗試運(yùn)行一下上面應(yīng)用,因?yàn)檫@里需要用到ZooKeeper來(lái)協(xié)調(diào)分布式環(huán)境下的任務(wù)調(diào)度。所以,你需要先在本地安裝ZooKeeper,然后啟動(dòng)它。注意:上面elasticjob.reg-center.server-lists配置,根據(jù)你實(shí)際使用的ZooKeeper地址和端口做相應(yīng)修改。

          在啟動(dòng)上述Spring Boot應(yīng)用之后,我們可以看到如下日志輸出:

          2021-07-20 15:33:39.541  INFO 56365 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'my-simple-job' initialized from an externally provided properties instance.
          2021-07-20 15:33:39.541  INFO 56365 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.3.2
          2021-07-20 15:33:39.551  INFO 56365 --- [           main] org.apache.curator.utils.Compatibility   : Using org.apache.zookeeper.server.quorum.MultipleAddresses
          2021-07-20 15:33:40.067  INFO 56365 --- [           main] c.d.chapter72.Chapter72Application       : Started Chapter72Application in 3.25 seconds (JVM running for 4.965)
          2021-07-20 15:33:40.069  INFO 56365 --- [           main] .s.b.j.ScheduleJobBootstrapStartupRunner : Starting ElasticJob Bootstrap.
          2021-07-20 15:33:40.078  INFO 56365 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler my-simple-job_$_NON_CLUSTERED started.
          2021-07-20 15:33:40.078  INFO 56365 --- [           main] .s.b.j.ScheduleJobBootstrapStartupRunner : ElasticJob Bootstrap started.
          2021-07-20 15:33:45.157  INFO 56365 --- [le-job_Worker-1] com.didispace.chapter72.MySimpleJob      : MySimpleJob start : didispace.com 1626766425157
          2021-07-20 15:33:50.010  INFO 56365 --- [le-job_Worker-1] com.didispace.chapter72.MySimpleJob      : MySimpleJob start : didispace.com 1626766430010
          2021-07-20 15:33:55.013  INFO 56365 --- [le-job_Worker-1] com.didispace.chapter72.MySimpleJob      : MySimpleJob start : didispace.com 1626766435013

          既然是分布式任務(wù)調(diào)度,那么我們?cè)賳?dòng)一個(gè)(注意,在同一臺(tái)機(jī)器啟動(dòng)的時(shí)候,會(huì)端口沖突,可以在啟動(dòng)命令中加入-Dserver.port=8081來(lái)區(qū)分端口),在第二個(gè)啟動(dòng)的服務(wù)日志也打印了類似的內(nèi)容

          2021-07-20 15:34:06.430  INFO 56371 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'my-simple-job' initialized from an externally provided properties instance.
          2021-07-20 15:34:06.430  INFO 56371 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.3.2
          2021-07-20 15:34:06.436  INFO 56371 --- [           main] org.apache.curator.utils.Compatibility   : Using org.apache.zookeeper.server.quorum.MultipleAddresses
          2021-07-20 15:34:06.786  INFO 56371 --- [           main] c.d.chapter72.Chapter72Application       : Started Chapter72Application in 1.446 seconds (JVM running for 1.884)
          2021-07-20 15:34:06.787  INFO 56371 --- [           main] .s.b.j.ScheduleJobBootstrapStartupRunner : Starting ElasticJob Bootstrap.
          2021-07-20 15:34:06.792  INFO 56371 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler my-simple-job_$_NON_CLUSTERED started.
          2021-07-20 15:34:06.792  INFO 56371 --- [           main] .s.b.j.ScheduleJobBootstrapStartupRunner : ElasticJob Bootstrap started.
          2021-07-20 15:34:10.182  INFO 56371 --- [le-job_Worker-1] com.didispace.chapter72.MySimpleJob      : MySimpleJob start : didispace.com 1626766450182
          2021-07-20 15:34:15.010  INFO 56371 --- [le-job_Worker-1] com.didispace.chapter72.MySimpleJob      : MySimpleJob start : didispace.com 1626766455010
          2021-07-20 15:34:20.013  INFO 56371 --- [le-job_Worker-1] com.didispace.chapter72.MySimpleJob      : MySimpleJob start : didispace.com 1626766460013

          此時(shí),在回頭看看之前第一個(gè)啟動(dòng)的應(yīng)用,日志輸出停止了。由于我們?cè)O(shè)置了分片總數(shù)為1,所以這個(gè)任務(wù)啟動(dòng)之后,只會(huì)有一個(gè)實(shí)例接管執(zhí)行。這樣就避免了多個(gè)進(jìn)行同時(shí)重復(fù)的執(zhí)行相同邏輯而產(chǎn)生問(wèn)題的情況。同時(shí),這樣也支持了任務(wù)執(zhí)行的高可用。比如:可以嘗試把第二個(gè)啟動(dòng)的應(yīng)用(正在打印日志的)終止掉??梢园l(fā)現(xiàn),第一個(gè)啟動(dòng)的應(yīng)用(之前已經(jīng)停止輸出日志)繼續(xù)開始打印任務(wù)日志了。

          在整個(gè)實(shí)現(xiàn)過(guò)程中,我們并沒(méi)有自己手工的去編寫任何的分布式鎖等代碼去實(shí)現(xiàn)任務(wù)調(diào)度邏輯,只需要關(guān)注任務(wù)邏輯本身,然后通過(guò)配置分片的方式來(lái)控制任務(wù)的分割,就可以輕松的實(shí)現(xiàn)分布式集群環(huán)境下的定時(shí)任務(wù)管理了。是不是在復(fù)雜場(chǎng)景下,這種方式實(shí)現(xiàn)起來(lái)要比@Scheduled更方便呢?

          記得自己動(dòng)手寫一寫,這樣體會(huì)更深哦!如果碰到問(wèn)題,可以拉取文末的代碼示例對(duì)比一下是否有地方配置不一樣。下一篇,我們還將繼續(xù)介紹關(guān)于定時(shí)任務(wù)的一些高級(jí)內(nèi)容。關(guān)注我,收藏本系列教程《Spring Boot 2.x基礎(chǔ)教程》點(diǎn)擊直達(dá)!(http://blog.didispace.com/spring-boot-learning-2x/)。

          學(xué)習(xí)過(guò)程中如遇困難,加入Spring技術(shù)交流群,參與討論

          關(guān)注我回復(fù)「加群」,加入Spring技術(shù)交流群


          代碼示例

          本文的完整工程可以查看下面?zhèn)}庫(kù)中的chapter7-2目錄:

          • 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)力!


          往期推薦

          Spring為什么建議使用構(gòu)造器來(lái)注入?

          Redis 內(nèi)存壓縮實(shí)戰(zhàn),學(xué)習(xí)了!

          微軟出手,干翻 IDEA?網(wǎng)友:先干翻Eclipse吧..

          OpenJDK 正式宣布AWT、2D、Swing等項(xiàng)目解散

          大廠籠罩下的無(wú)奈,什么時(shí)候才是個(gè)頭?


          瀏覽 32
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久草A片 AV黄色片 | 天堂俺去俺来也www久久婷婷 | 高清无码毛毛片 | 一本大道久久久久 | 大香蕉伊人免费在线视频 |