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

可以根據(jù)需要修改 xxl-job-admin 的配置文件,主要是修改數(shù)據(jù)源信息,若需要用到郵件報(bào)警功能,需要配置郵箱。
然后啟動(dòng)項(xiàng)目,正常啟動(dòng)后,訪問(wèn)地址為:http://localhost:8080/xxl-job-admin,默認(rèn)的賬戶為 admin,密碼為 123456,訪問(wèn)后臺(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)映射端口問(wèn)題。
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ǔ)磁盤(pán)路徑?[選填]?:需要對(duì)該路徑擁有讀寫(xiě)權(quán)限;為空則使用默認(rèn)路徑;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
###?執(zhí)行器日志文件保存天數(shù)?[選填]?:?過(guò)期日志自動(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;
????}
}
接下來(lái)就可以創(chuàng)建任務(wù)了。
編寫(xiě) JobHandler
在這里主要演示下 Bean 模式的任務(wù),可以基于類和方法進(jìn)行開(kāi)發(fā),下面先介紹基于類的開(kāi)發(fā)的任務(wù)。
BEAN模式(類形式)
首先創(chuàng)建一個(gè)類 BeanClassJobHandler,繼承 IJobHandler 實(shí)現(xiàn) execute 方法,然后通過(guò) XxlJobLogger.log 來(lái)打印日志。
@Component
public?class?BeanClassJobHandler?extends?IJobHandler?{
????@Override
????public?ReturnT?execute(String?param)?throws?Exception?{
????????XxlJobLogger.log("bean?class?jobhandler?running...");
????????return?ReturnT.SUCCESS;
????}
}
基于類開(kāi)發(fā)的任務(wù)需要手動(dòng)注冊(cè)到執(zhí)行器工廠,具體代碼如下所示:
XxlJobSpringExecutor.registJobHandler("beanClassJobHandler",?new?BeanClassJobHandler());
到此一個(gè)任務(wù)就開(kāi)發(fā)完成了,下面介紹下基于方法的開(kāi)發(fā)方式:
BEAN模式(方法形式)
基于方法開(kāi)發(fā)的任務(wù)比較簡(jiǎn)單,編寫(xiě)一個(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)目就開(kāi)發(fā)完成了,啟動(dòng)項(xiàng)目,在執(zhí)行器管理頁(yè)面添加該執(zhí)行器。
新增執(zhí)行器執(zhí)行器添加完成后,需要在任務(wù)管理界面添加我們剛才開(kāi)發(fā)的兩個(gè)任務(wù),下面以 BEAN 模式方法任務(wù)為例:
新增任務(wù)點(diǎn)擊保存后,一個(gè)定時(shí)任務(wù)就完成了,是不是很簡(jiǎn)單呢?
下面啟動(dòng)任務(wù)來(lái)查看下執(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 的集成是不是很簡(jiǎn)單呢?在這里只是簡(jiǎn)單地入門(mén),想要了解更多可以看下官方文檔:https://www.xuxueli.com/xxl-job。
還沒(méi)有使用過(guò)的可以通過(guò)本文快速上手,來(lái)實(shí)操起來(lái)吧!
本文的完整代碼在 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
