任务调度错过触发时间时的处理策略:
- 可能原因:服务重启;调度线程被阻塞,线程被耗尽;上次调度持续阻塞,下次调度被错过; - 处理策略: - 过期超10s:本地忽略,当前时间开始计算下次触发时间 - 过期超过5s:过期10s内:立即触发一次,当前时间开始计算下次触发时间
This commit is contained in:
parent
e01d2bc9b5
commit
5c1f59323e
|
@ -836,11 +836,11 @@ XXL-JOB调度模块默认采用并行机制,在多线程调度的情况下,
|
||||||
XXL-JOB的每个调度任务虽然在调度模块是并行调度执行的,但是任务调度传递到任务模块的“执行器”确实串行执行的,同时支持任务终止。
|
XXL-JOB的每个调度任务虽然在调度模块是并行调度执行的,但是任务调度传递到任务模块的“执行器”确实串行执行的,同时支持任务终止。
|
||||||
|
|
||||||
#### 5.4.6 过期处理策略
|
#### 5.4.6 过期处理策略
|
||||||
任务调度错过了触发时间:
|
任务调度错过触发时间时的处理策略:
|
||||||
- 可能原因:服务重启;调度线程被阻塞,线程被耗尽;上次调度持续阻塞,下次调度被错过;
|
- 可能原因:服务重启;调度线程被阻塞,线程被耗尽;上次调度持续阻塞,下次调度被错过;
|
||||||
- 处理策略:
|
- 处理策略:
|
||||||
- 过期5s内:立即触发一次,并计算下次触发时间;
|
- 过期超10s:本地忽略,当前时间开始计算下次触发时间
|
||||||
- 过期超过5s:忽略过期触发,计算下次触发时间;
|
- 过期超过5s:过期10s内:立即触发一次,当前时间开始计算下次触发时间
|
||||||
|
|
||||||
|
|
||||||
#### 5.4.7 日志回调服务
|
#### 5.4.7 日志回调服务
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package com.xxl.job.admin.core.thread;
|
package com.xxl.job.admin.core.thread;
|
||||||
|
|
||||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
||||||
import com.xxl.job.admin.core.model.XxlJobInfo;
|
|
||||||
import com.xxl.job.admin.core.cron.CronExpression;
|
import com.xxl.job.admin.core.cron.CronExpression;
|
||||||
|
import com.xxl.job.admin.core.model.XxlJobInfo;
|
||||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -58,7 +58,7 @@ public class JobScheduleHelper {
|
||||||
|
|
||||||
// tx start
|
// tx start
|
||||||
|
|
||||||
// 1、查询JOB:"下次调度30s内" ( ...... -5 ... now ...... +30 ...... )
|
// 1、查询JOB:"下次调度30s内"
|
||||||
long maxNextTime = System.currentTimeMillis() + 30000;
|
long maxNextTime = System.currentTimeMillis() + 30000;
|
||||||
long nowTime = System.currentTimeMillis();
|
long nowTime = System.currentTimeMillis();
|
||||||
List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(maxNextTime);
|
List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(maxNextTime);
|
||||||
|
@ -66,35 +66,53 @@ public class JobScheduleHelper {
|
||||||
// 2、推送时间轮
|
// 2、推送时间轮
|
||||||
for (XxlJobInfo jobInfo: scheduleList) {
|
for (XxlJobInfo jobInfo: scheduleList) {
|
||||||
|
|
||||||
// 过期策略:过期=更新下次触发时间为当前、过期是否5s内=立即出发,否则忽略;
|
// 时间轮刻度计算
|
||||||
if (jobInfo.getTriggerNextTime() < nowTime) {
|
int ringSecond = -1;
|
||||||
jobInfo.setTriggerNextTime(nowTime);
|
if (jobInfo.getTriggerNextTime() < nowTime - 10000) { // 过期超10s:本地忽略,当前时间开始计算下次触发时间
|
||||||
if (jobInfo.getTriggerNextTime() < nowTime-10000) {
|
ringSecond = -1;
|
||||||
continue;
|
|
||||||
}
|
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
||||||
|
jobInfo.setTriggerNextTime(
|
||||||
|
new CronExpression(jobInfo.getJobCron())
|
||||||
|
.getNextValidTimeAfter(new Date())
|
||||||
|
.getTime()
|
||||||
|
);
|
||||||
|
} else if (jobInfo.getTriggerNextTime() < nowTime) { // 过期10s内:立即触发一次,当前时间开始计算下次触发时间
|
||||||
|
ringSecond = (int)((nowTime/1000)%60);
|
||||||
|
|
||||||
|
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
||||||
|
jobInfo.setTriggerNextTime(
|
||||||
|
new CronExpression(jobInfo.getJobCron())
|
||||||
|
.getNextValidTimeAfter(new Date())
|
||||||
|
.getTime()
|
||||||
|
);
|
||||||
|
} else { // 未过期:正常触发,递增计算下次触发时间
|
||||||
|
ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);
|
||||||
|
|
||||||
|
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
||||||
|
jobInfo.setTriggerNextTime(
|
||||||
|
new CronExpression(jobInfo.getJobCron())
|
||||||
|
.getNextValidTimeAfter(new Date(jobInfo.getTriggerNextTime()))
|
||||||
|
.getTime()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (ringSecond == -1) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// push async ring
|
// push async ring
|
||||||
int second = (int)((jobInfo.getTriggerNextTime()/1000)%60);
|
List<Integer> ringItemData = ringData.get(ringSecond);
|
||||||
List<Integer> ringItemData = ringData.get(second);
|
|
||||||
if (ringItemData == null) {
|
if (ringItemData == null) {
|
||||||
ringItemData = new ArrayList<Integer>();
|
ringItemData = new ArrayList<Integer>();
|
||||||
ringData.put(second, ringItemData);
|
ringData.put(ringSecond, ringItemData);
|
||||||
}
|
}
|
||||||
ringItemData.add(jobInfo.getId());
|
ringItemData.add(jobInfo.getId());
|
||||||
|
|
||||||
logger.info(">>>>>>>>>>> xxl-job, push time-ring : " + second + " = " + Arrays.asList(ringItemData) );
|
logger.info(">>>>>>>>>>> xxl-job, push time-ring : " + ringSecond + " = " + Arrays.asList(ringItemData) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3、更新trigger信息
|
// 3、更新trigger信息
|
||||||
for (XxlJobInfo jobInfo: scheduleList) {
|
for (XxlJobInfo jobInfo: scheduleList) {
|
||||||
// update
|
|
||||||
jobInfo.setTriggerLastTime(jobInfo.getTriggerNextTime());
|
|
||||||
jobInfo.setTriggerNextTime(
|
|
||||||
new CronExpression(jobInfo.getJobCron())
|
|
||||||
.getNextValidTimeAfter(new Date(jobInfo.getTriggerNextTime()))
|
|
||||||
.getTime()
|
|
||||||
);
|
|
||||||
XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo);
|
XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,28 +159,22 @@ public class JobScheduleHelper {
|
||||||
List<Integer> ringItemData = new ArrayList<>();
|
List<Integer> ringItemData = new ArrayList<>();
|
||||||
int nowSecond = (int)((System.currentTimeMillis()/1000)%60); // 避免处理耗时太长,跨过刻度;
|
int nowSecond = (int)((System.currentTimeMillis()/1000)%60); // 避免处理耗时太长,跨过刻度;
|
||||||
if (lastSecond == -1) {
|
if (lastSecond == -1) {
|
||||||
if (ringData.containsKey(nowSecond)) {
|
lastSecond = (nowSecond+59)%60;
|
||||||
List<Integer> tmpData = ringData.remove(nowSecond);
|
|
||||||
if (tmpData != null) {
|
|
||||||
ringItemData.addAll(tmpData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastSecond = nowSecond;
|
|
||||||
} else {
|
|
||||||
for (int i = 1; i <=60; i++) {
|
|
||||||
int secondItem = (lastSecond+i)%60;
|
|
||||||
|
|
||||||
List<Integer> tmpData = ringData.remove(secondItem);
|
|
||||||
if (tmpData != null) {
|
|
||||||
ringItemData.addAll(tmpData);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondItem == nowSecond) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastSecond = nowSecond;
|
|
||||||
}
|
}
|
||||||
|
for (int i = 1; i <=60; i++) {
|
||||||
|
int secondItem = (lastSecond+i)%60;
|
||||||
|
|
||||||
|
List<Integer> tmpData = ringData.remove(secondItem);
|
||||||
|
if (tmpData != null) {
|
||||||
|
ringItemData.addAll(tmpData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondItem == nowSecond) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastSecond = nowSecond;
|
||||||
|
|
||||||
|
|
||||||
logger.info(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) );
|
logger.info(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) );
|
||||||
if (ringItemData!=null && ringItemData.size()>0) {
|
if (ringItemData!=null && ringItemData.size()>0) {
|
||||||
|
@ -171,7 +183,6 @@ public class JobScheduleHelper {
|
||||||
// do trigger
|
// do trigger
|
||||||
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
|
JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear
|
// clear
|
||||||
ringItemData.clear();
|
ringItemData.clear();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue