Spring Boot 集成 XXL-JOB 任務(wù)調(diào)度平臺(tái)
在開發(fā)中需要將已有的定時(shí)任務(wù)抽離出來,方便管理查看,因此選擇集成分布式任務(wù)調(diào)度平臺(tái) XXL-JOB,本文就講解下 Spring Boot 如何集成 XXL-JOB 任務(wù)調(diào)度平臺(tái)。
XXL-JOB 簡介
XXL-JOB是一個(gè)分布式任務(wù)調(diào)度平臺(tái),其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡單、輕量級(jí)、易擴(kuò)展。現(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用。
下面我們?cè)?Spring Boot 中集成 XXL-JOB 來完成定時(shí)任務(wù)的編寫(本文選擇的 XXL-JOB 版本為 2.2.0)。
Spring Boot 集成 XXL-JOB
Spring Boot 集成 XXL-JOB 主要分為以下兩步:
- 配置運(yùn)行調(diào)度中心(xxl-job-admin)
- 配置運(yùn)行執(zhí)行器項(xiàng)目(xxl-job-executor)
配置運(yùn)行調(diào)度中心
首先從源碼倉庫中下載代碼,代碼地址有兩個(gè):
- GitHub:https://github.com/xuxueli/xxl-job
- Gitee:http://gitee.com/xuxueli0323/xxl-job
下載完之后,在 doc/db 目錄下有數(shù)據(jù)庫腳本 tables_xxl_job.sql,執(zhí)行下腳本初始化調(diào)度數(shù)據(jù)庫 xxl_job,如下圖所示:

可以根據(jù)需要修改 xxl-job-admin 的配置文件,主要是修改數(shù)據(jù)源信息,若需要用到郵件報(bào)警功能,需要配置郵箱。
然后啟動(dòng)項(xiàng)目,正常啟動(dòng)后,訪問地址為:http://localhost:8080/xxl-job-admin,默認(rèn)的賬戶為 admin,密碼為 123456,訪問后臺(tái)管理系統(tǒng)后臺(tái),界面如下:

這樣就表示調(diào)度中心已經(jīng)搞定了,下一步就是創(chuàng)建執(zhí)行器項(xiàng)目。
配置運(yùn)行執(zhí)行器項(xiàng)目
創(chuàng)建一個(gè)項(xiàng)目,在項(xiàng)目中加入 xxl-job-core 依賴,項(xiàng)目依賴如下所示:
?org.springframework.boot
?spring-boot-starter-web
?com.xuxueli
?xxl-job-core
?2.2.0
加入配置
在配置文件 application.properties 中配置 xxl-job 執(zhí)行器的相關(guān)參數(shù),具體內(nèi)容如下:
###?調(diào)度中心部署跟地址?[選填]:如調(diào)度中心集群部署存在多個(gè)地址則用逗號(hào)分隔。執(zhí)行器將會(huì)使用該地址進(jìn)行"執(zhí)行器心跳注冊(cè)"和"任務(wù)結(jié)果回調(diào)";為空則關(guān)閉自動(dòng)注冊(cè);
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
###?執(zhí)行器通訊TOKEN [選填]:非空時(shí)啟用;
xxl.job.accessToken=
###?執(zhí)行器AppName [選填]:執(zhí)行器心跳注冊(cè)分組依據(jù);為空則關(guān)閉自動(dòng)注冊(cè)
xxl.job.executor.appname=xxl-job-executor
###?執(zhí)行器注冊(cè)?[選填]:優(yōu)先使用該配置作為注冊(cè)地址,為空時(shí)使用內(nèi)嵌服務(wù)?”IP:PORT“?作為注冊(cè)地址。從而更靈活的支持容器類型執(zhí)行器動(dòng)態(tài)IP和動(dòng)態(tài)映射端口問題。
xxl.job.executor.address=
###?執(zhí)行器IP [選填]:默認(rèn)為空表示自動(dòng)獲取IP,多網(wǎng)卡時(shí)可手動(dòng)設(shè)置指定IP,該IP不會(huì)綁定Host僅作為通訊的時(shí)候用;地址信息用于?"執(zhí)行器注冊(cè)"?和?"調(diào)度中心請(qǐng)求并觸發(fā)任務(wù)";
xxl.job.executor.ip=
###?執(zhí)行器端口號(hào)?[選填]:小于等于0則自動(dòng)獲??;默認(rèn)端口為9999,單機(jī)部署多個(gè)執(zhí)行器時(shí),注意要配置不同執(zhí)行器端口;
xxl.job.executor.port=9999
###?執(zhí)行器運(yùn)行日志文件存儲(chǔ)磁盤路徑?[選填]?:需要對(duì)該路徑擁有讀寫權(quán)限;為空則使用默認(rèn)路徑;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
###?執(zhí)行器日志文件保存天數(shù)?[選填]?:?過期日志自動(dòng)清理, 限制值大于等于3時(shí)生效;?否則, 如-1, 關(guān)閉自動(dòng)清理功能;
xxl.job.executor.logretentiondays=30
其中指定了上一步部署的調(diào)度中心的地址和執(zhí)行器的相關(guān)參數(shù)。
然后在 config 包下創(chuàng)建 XxlJobConfiguration 類,會(huì)從配置文件中讀取到對(duì)應(yīng)的參數(shù),接著申明一個(gè) xxlJobExecutor 方法,返回的是一個(gè) XxlJobSpringExecutor,這個(gè)方法主要是如何初始化并創(chuàng)建一個(gè) XxlJobSpringExecutor。
@Configuration
public?class?XxlJobConfiguration?{
????private?Logger?logger?=?LoggerFactory.getLogger(XxlJobConfiguration.class);
????@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()?{
????????logger.info(">>>>>>>>>>>?xxl-job?config?init.");
????????//?registry?jobhandler
????????XxlJobSpringExecutor.registJobHandler("beanClassJobHandler",?new?BeanClassJobHandler());
????????//?init?executor
????????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;
????}
}
接下來就可以創(chuàng)建任務(wù)了。
編寫 JobHandler
在這里主要演示下 Bean 模式的任務(wù),可以基于類和方法進(jìn)行開發(fā),下面先介紹基于類的開發(fā)的任務(wù)。
BEAN模式(類形式)
首先創(chuàng)建一個(gè)類 BeanClassJobHandler,繼承 IJobHandler 實(shí)現(xiàn) execute 方法,然后通過 XxlJobLogger.log 來打印日志。
@Component
public?class?BeanClassJobHandler?extends?IJobHandler?{
????@Override
????public?ReturnT?execute(String?param)?throws?Exception?{
????????XxlJobLogger.log("bean?class?jobhandler?running...");
????????return?ReturnT.SUCCESS;
????}
}
基于類開發(fā)的任務(wù)需要手動(dòng)注冊(cè)到執(zhí)行器工廠,具體代碼如下所示:
XxlJobSpringExecutor.registJobHandler("beanClassJobHandler",?new?BeanClassJobHandler());
到此一個(gè)任務(wù)就開發(fā)完成了,下面介紹下基于方法的開發(fā)方式:
BEAN模式(方法形式)
基于方法開發(fā)的任務(wù)比較簡單,編寫一個(gè)方法,并添加 @XxlJob 注解,會(huì)自動(dòng)掃描該任務(wù)并注入到執(zhí)行器容器。
@Component
public?class?BeanMethodJobHandler?{
????@XxlJob("beanMethodJobHandler")
????public?ReturnT?beanMethodJobHandler(String?param)?throws?Exception?{
????????XxlJobLogger.log("bean?method?jobhandler?running...");
????????return?ReturnT.SUCCESS;
????}
}
至此,執(zhí)行器項(xiàng)目就開發(fā)完成了,啟動(dòng)項(xiàng)目,在執(zhí)行器管理頁面添加該執(zhí)行器。
新增執(zhí)行器執(zhí)行器添加完成后,需要在任務(wù)管理界面添加我們剛才開發(fā)的兩個(gè)任務(wù),下面以 BEAN 模式方法任務(wù)為例:
新增任務(wù)點(diǎn)擊保存后,一個(gè)定時(shí)任務(wù)就完成了,是不是很簡單呢?
下面啟動(dòng)任務(wù)來查看下執(zhí)行結(jié)果,在這里點(diǎn)擊“執(zhí)行一次”,然后查詢執(zhí)行日志,結(jié)果如下圖:
執(zhí)行日志可以看到我們的任務(wù)已經(jīng)成功執(zhí)行了,至此,Spring Boot 集成 XXL-JOB 任務(wù)調(diào)度平臺(tái)就完成了。
總結(jié)Spring Boot 與 XXL-JOB 的集成是不是很簡單呢?在這里只是簡單地入門,想要了解更多可以看下官方文檔:https://www.xuxueli.com/xxl-job。
還沒有使用過的可以通過本文快速上手,來實(shí)操起來吧!
本文的完整代碼在 https://github.com/wupeixuan/SpringBoot-Learn 的 xxl-job-executor 目錄下。
最好的關(guān)系就是互相成就,大家的點(diǎn)贊、在看、分享、留言就是我創(chuàng)作的最大動(dòng)力。
參考
https://www.xuxueli.com/xxl-job
https://github.com/wupeixuan/SpringBoot-Learn
