xxLjob兩個任務 pullGuanjiaSalesJob,不同的執行參數,配置了同一個 @XxlJob("pullGuanjiaSalesJob")兩個任務同一個調用時間 CRON:0 0 3 * * ?,具體如何調度的,及任務如何執行的
在 XXL-JOB 中,當兩個任務配置了相同的?@XxlJob("pullGuanjiaSalesJob")
?方法且 CRON 表達式相同(如?0 0 3 * * ?
,即每天凌晨3點觸發),其調度和執行流程如下:
1. 調度中心的觸發機制
(1) 任務存儲與觸發檢查
XXL-JOB Admin(調度中心)?會定期掃描任務表(默認每秒一次),檢查到達觸發時間的任務。
如果兩個任務的 CRON 表達式均為?
0 0 3 * * ?
,調度中心會在?同一時間點(3:00:00)?生成兩條任務觸發記錄。
(2) 任務觸發順序
默認并發觸發:
調度中心會?同時?向執行器發送兩個任務的觸發請求(即使?jobHandler
?相同),但會攜帶不同的?jobId
?和參數(如?param=type=daily
?和?param=type=monthly
)。阻塞策略影響:
如果任務配置了?SERIAL_EXECUTION
(串行執行),調度中心會按任務ID順序依次觸發(前一個任務執行完成后,再觸發下一個)。
2. 執行器的任務執行
(1) 任務分發到執行器
調度中心通過 RPC 調用執行器(Executor),傳遞以下信息:
jobHandler
:pullGuanjiaSalesJob
(兩個任務相同)。jobParam
:任務參數(如?type=daily
?和?type=monthly
)。jobId
:任務唯一ID(區分不同任務實例)。
執行器會根據?
jobId
?和?jobParam
?區分任務,即使?jobHandler
?相同。
(2) 執行器線程池處理
執行器接收到任務后,會提交到內置的線程池(默認核心線程數為?
8
)。默認并發執行:兩個任務會由不同線程同時執行。
串行執行:如果配置了?
SERIAL_EXECUTION
,則任務會排隊依次執行。
(3) 任務方法執行
java
@XxlJob("pullGuanjiaSalesJob") public ReturnT<String> pullGuanjiaSalesJob(String param) {if ("type=daily".equals(param)) {// 執行每日統計邏輯} else if ("type=monthly".equals(param)) {// 執行月度統計邏輯}return ReturnT.SUCCESS; }
通過?
param
?區分不同任務的業務邏輯。
3. 關鍵影響因素
(1) 阻塞策略(Block Strategy)
策略 | 對相同?jobHandler ?任務的影響 |
---|---|
SERIAL_EXECUTION | 串行執行(按任務ID順序,前一個完成后再觸發下一個)。 |
DISCARD_LATER | 丟棄后續觸發,只執行第一個到達的任務。 |
COVER_EARLY | 覆蓋早期觸發,只執行最新的一個任務。 |
(2) 執行器線程池配置
線程池大小通過?
xxl.job.executor.corePoolSize
?配置(默認8)。若線程池已滿,新任務會等待或丟棄(取決于配置)。
4. 執行流程示例
場景描述
任務1:
jobId=1
,param=type=daily
,阻塞策略為?SERIAL_EXECUTION
。任務2:
jobId=2
,param=type=monthly
,阻塞策略為?SERIAL_EXECUTION
。
執行步驟
調度中心?在 3:00:00 同時檢測到兩個任務需觸發。
由于?
jobHandler
?相同且阻塞策略為?SERIAL_EXECUTION
,調度中心按?jobId
?順序觸發:先觸發?
jobId=1
(type=daily
),等待其執行完成。完成后觸發?
jobId=2
(type=monthly
)。
執行器依次運行兩個任務,通過?
param
?區分邏輯。
5. 如何避免問題?
(1) 確保參數可區分邏輯
在?
@XxlJob
?方法內明確解析?param
,避免邏輯沖突。示例:
java
@XxlJob("pullGuanjiaSalesJob") public ReturnT<String> execute(String param) {if (param == null) {return ReturnT.FAIL;}switch (param) {case "type=daily":// 每日邏輯break;case "type=monthly":// 月度邏輯break;}return ReturnT.SUCCESS; }
(2) 調整阻塞策略
若任務需嚴格串行,配置?
SERIAL_EXECUTION
。若允許并發,但需避免資源競爭,可在代碼中加鎖:
java
private final Object lock = new Object();@XxlJob("pullGuanjiaSalesJob") public ReturnT<String> execute(String param) {synchronized (lock) {// 業務邏輯}return ReturnT.SUCCESS; }
(3) 監控與日志
在任務日志中記錄?
jobId
?和?param
,便于排查問題:java
@XxlJob("pullGuanjiaSalesJob") public ReturnT<String> execute(String param) {log.info("Job started: jobId={}, param={}", XxlJobHelper.getJobId(), param);// 業務邏輯return ReturnT.SUCCESS; }
6. 總結
調度機制:相同 CRON 的任務會同時觸發,但執行順序受阻塞策略控制。
執行邏輯:通過?
jobParam
?區分任務,由執行器線程池并發或串行執行。最佳實踐:
使用參數明確區分任務邏輯。
關鍵任務配置?
SERIAL_EXECUTION
?避免并發問題。監控日志確保任務按預期執行。