问题描述:Quartz暂停后,恢复出现多次执行Job,下面是源码操作
1、Quartz创建一个Job任务,这个很简单
/**
* 新增/修改任务
* @param quartz
* @return
*/
@Override
public Result saveJob(QuartzJob quartz,Object obj){
try {
//如果是修改 展示旧的 任务
if(quartz.getOldJobGroup() != null && !"".equals(quartz.getOldJobGroup())){
JobKey key = new JobKey(quartz.getOldJobName(),quartz.getOldJobGroup());
scheduler.deleteJob(key);
}
//构建job信息
//构建job信息
Class cls = null;
//第一种方式:从页面传入值 如:包+类 包名获取class对象
if (StringUtils.isNotEmpty(quartz.getJobClassName())){
cls = Class.forName(quartz.getJobClassName());
}
//第二种方式:直接使用obj对象获取class
if (cls==null&&obj!=null){
cls = obj.getClass();
}
cls.newInstance();
JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
quartz.getJobGroup())
.withDescription(quartz.getDescription()).build();
//添加参数
job.getJobDataMap().put("jobParam", quartz.getJobDataParam());
// 触发时间点
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression().trim());
cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup())
.startNow().withPriority(quartz.getPriority()).withSchedule(cronScheduleBuilder).build();
//交由Scheduler安排触发
scheduler.scheduleJob(job, trigger);
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
return Result.ok();
}
2、暂停Job任务
/**
* 停止任务
* @param jobName
* @param jobGroup
* @return
*/
@Override
public Result pauseJob(String jobName, String jobGroup) {
JobKey key = new JobKey(jobName,jobGroup);
try {
scheduler.pauseJob(key);
} catch (SchedulerException e) {
e.printStackTrace();
return Result.error();
}
return Result.ok();
}```
3、恢复Job任务
```java
/**
* 恢复任务
* @param jobName
* @param jobGroup
* @return
*/
@Override
public Result resumeJob(String jobName, String jobGroup) {
JobKey key = new JobKey(jobName,jobGroup);
try {
scheduler.resumeJob(key);
} catch (SchedulerException e) {
e.printStackTrace();
return Result.error();
}
return Result.ok();
}
结果:
暂停是没问题,恢复Job就出现多次执行Job情况,经过定位和查找资料,发现Quartz暂停后 恢复启动 为什么会执行多次 会把暂停中间需要执行的次数在恢复启动时一次补偿执行完毕
cronScheduleBuilder.withMisfireHandlingInstructionDoNothing();因为这正是WithMisfireHandlingInstructionIgnoreMisfires()所要求的,重做所有错过的周期。
但是知道原理,还是要解决现实问题。
quartz.properties中还需要配置这个参数值,要正确的值,如下:
#这个时间大于10000(10秒)会导致MISFIRE_INSTRUCTION_DO_NOTHING不起作用。
org.quartz.jobStore.misfireThreshold = 6000
好啦,问题保管解决,不解决你找我!
解释下这个配置设置的意义:
misfireThreshold表示实际执行时间与下一次应该执行时间之间的差值,超过这个差值就不会执行,低于这个差值就会执行。
比如我每3秒执行一次,misfireThreshold=6000,当你暂停低于6秒内,它会弥补执行,超过6秒,它就不再弥补执行了。