Springboot集成分布式任務(wù)調(diào)度系統(tǒng)XXl-Job(調(diào)度器和執(zhí)行器)
一、部署xxl-job服務(wù)端
下載xxl-job源碼
下載地址:https://gitee.com/xuxueli0323/xxl-job
二、導(dǎo)入項目、創(chuàng)建xxl_job數(shù)據(jù)庫、修改配置文件為自己的數(shù)據(jù)庫
三、啟動項目、訪問首頁
訪問地址:http://localhost:8080/xxl-job-admin/ 賬號:admin 密碼:123456.
執(zhí)行器管理
我們部署的是調(diào)度器管理平臺,執(zhí)行器就是我們實際開發(fā)的應(yīng)用系統(tǒng):比如:會員系統(tǒng)、訂單系統(tǒng)、結(jié)算系統(tǒng)等等;執(zhí)行器管理可以對每一個注冊上來的執(zhí)行器進(jìn)行管理(編輯、刪除執(zhí)行器等)。
任務(wù)管理
我們應(yīng)用系統(tǒng)都會有自己特定的job任務(wù):比如:會員系統(tǒng)定時拉取一些會員推送模板消息、短信消息;結(jié)算系統(tǒng)定時生成結(jié)算任務(wù)、報表等。任務(wù)管理可根據(jù)具體的執(zhí)行器、job任務(wù)名稱(JobHandler)、任務(wù)描述等進(jìn)行篩選;可新增任務(wù)、啟動任務(wù)、執(zhí)行任務(wù)、查詢調(diào)度日志,功能比較豐富。
用戶管理
用戶管理可根據(jù)角色(普通用戶、管理員)進(jìn)行管理:新增用戶、刪除用戶。
調(diào)度日志
在調(diào)度日志模塊可查詢我們執(zhí)行任務(wù)時的具體情況,可根據(jù)具體的執(zhí)行器、任務(wù)名稱、執(zhí)行狀態(tài)進(jìn)行篩選(成功、失敗、進(jìn)行中),對于進(jìn)行中的任務(wù)可手動終止;調(diào)度備注列可查看調(diào)度詳情,比如:我們的任務(wù)被調(diào)度到哪一臺機(jī)器、調(diào)度的結(jié)果碼、結(jié)果信息等等。
運(yùn)行報表
運(yùn)行報表是對調(diào)度平臺中執(zhí)行器數(shù)、任務(wù)數(shù)、調(diào)度次數(shù)、調(diào)度明細(xì)(成功、失?。?shù)據(jù)的匯總統(tǒng)計。
四、新建結(jié)算系統(tǒng)執(zhí)行器【僅僅是個demo案例】
看到此處,想必大家心中對xxl-job已經(jīng)有了一些初步的了解和感受,摩拳擦掌,趁熱打鐵,下面我們新建一個結(jié)算系統(tǒng)應(yīng)用,注冊到調(diào)度平臺,并新建一個月結(jié)任務(wù),測試下吧。
引入xxl-job調(diào)度器依賴
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
application.properties配置文件新增xxl-job配置
#xxljob config
#調(diào)度器地址
xxl.job.admin.addresses = http://127.0.0.1:8080/xxl-job-admin
#鑒權(quán)用暫無
xxl.job.accessToken =
#執(zhí)行器名稱(就是我們的業(yè)務(wù)系統(tǒng))
xxl.job.executor.appname = settle-system
#執(zhí)行器地址和ip,demo案例無需填寫
xxl.job.executor.address =
xxl.job.executor.ip =
#執(zhí)行器端口:默認(rèn)值:9999
xxl.job.executor.port = 9999
#日志路徑
xxl.job.executor.logpath = D:\\tmp\\log
#日志清理時間
xxl.job.executor.logretentiondays = 30
執(zhí)行器配置類(XxlJobConfig.java):
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Value;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.springframework.context.annotation.Configuration;
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.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.");
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;
}
編寫結(jié)算系統(tǒng)-月結(jié)job任務(wù)(MonthlySettlementJobHandler.java)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.xxl.job.core.handler.annotation.XxlJob;
@Component
public class MonthlySettlementJobHandler {
private static Logger logger = LoggerFactory.getLogger(MonthlySettlementJobHandler.class);
// 使用@XxlJob注解,將monthlySettlementJobHandler任務(wù)注冊到調(diào)度平臺
@XxlJob("monthlySettlementJobHandler")
public void monthlySettlementJobHandler(String param) throws InterruptedException {
try {
logger.info("結(jié)算系統(tǒng)-月結(jié)任務(wù)執(zhí)行 參數(shù): {}", param);
} catch (Exception e) {
logger.error("結(jié)算系統(tǒng)-月結(jié)任務(wù)執(zhí)行 異常 參數(shù): {} 異常信息: ", param, e);
}
}
}
結(jié)算系統(tǒng)執(zhí)行器代碼編寫完畢,啟動成功后,就需要去調(diào)度器管理平臺新建我們的執(zhí)行器、以及我們的job任務(wù)了。
在調(diào)度平臺新建結(jié)算系統(tǒng)執(zhí)行器
- AppName:對應(yīng)我們的配置:xxl.job.executor.appname = settle-system。
- 名稱:根據(jù)實際情況填寫(結(jié)算系統(tǒng))。
- 注冊方式:選擇自動注冊就可以了,結(jié)算系統(tǒng)在啟動的時候,會自動向調(diào)度平臺注冊。
- 機(jī)器地址:注冊方式選擇手動錄入時才需要填寫,此處我們無需填寫。
新建完畢之后,在列表頁面具體的執(zhí)行器了,點(diǎn)擊OnLine 機(jī)器地址,可查看執(zhí)行器的ip和端口。
在調(diào)度平臺新建結(jié)算系統(tǒng)調(diào)度任務(wù)
- 執(zhí)行器:選擇結(jié)算系統(tǒng)
- 任務(wù)描述:結(jié)算系統(tǒng)-月結(jié)任務(wù)
- 負(fù)責(zé)人:根據(jù)實際情況填寫
- 報警郵件:根據(jù)實際情況填寫
- 調(diào)度類型:選擇CRON
- Cron:填寫Cron表達(dá)式:0 0 3 * * ? (每日凌晨3.00執(zhí)行一次)
- 運(yùn)行模式:Bean
- JobHandler:就是我們編寫的月結(jié)job任務(wù)代碼中@XxlJob注解指定的名稱:
monthlySettlementJobHandler - 任務(wù)參數(shù):根據(jù)實際情況填寫,此demo案例沒有使用參數(shù)
- 路由策略:策略較多,此處我們選擇第一個
- 子任務(wù)ID:暫未
- 調(diào)度過期策略:忽略
- 阻塞處理策略:根據(jù)實際情況填寫,此處我們選擇單機(jī)串行
- 任務(wù)超時時間:單位:秒,根據(jù)實際情況填寫,此處是3秒
- 失敗重試次數(shù):根據(jù)實際情況填寫,此處我們選擇不重試:0
執(zhí)行結(jié)算系統(tǒng)-月結(jié)任務(wù)
點(diǎn)擊:操作--》執(zhí)行一次--》根據(jù)實際情況填寫job參數(shù)--》機(jī)器地址無需填寫。
執(zhí)行后,去結(jié)算系統(tǒng)查看日志,會有相應(yīng)業(yè)務(wù)日志輸出。
再回到調(diào)度平臺,點(diǎn)擊:操作--》查詢?nèi)罩?-》可看到調(diào)度時間、調(diào)度結(jié)果等等。
四、總結(jié)
從調(diào)度平臺部署、到業(yè)務(wù)應(yīng)用系統(tǒng)(結(jié)算系統(tǒng))對接調(diào)度平臺、編寫月結(jié)job任務(wù),總體流程大家應(yīng)該都比較清晰了,是不是覺得還挺簡單的,會不會又有些疑問,對接步驟這么簡潔,其背后的原理究竟是什么?