您的位置:首页 > 其它

quartz 暂停后重新启动,在暂停时 被暂停后的任务,在启动后会补偿执行即 会连续多次调用job中的execute方法。

2015-11-23 16:37 489 查看
调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则

CronTrigger 

withMisfireHandlingInstructionDoNothing

——不触发立即执行

——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行

withMisfireHandlingInstructionIgnoreMisfires

——以错过的第一个频率时间立刻开始执行

——重做错过的所有频率周期后

——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行

withMisfireHandlingInstructionFireAndProceed

——以当前时间为触发频率立刻触发一次执行

——然后按照Cron频率依次执行

SimpleTrigger 

withMisfireHandlingInstructionFireNow

——以当前时间为触发频率立即触发执行

——执行至FinalTIme的剩余周期次数

——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到

——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值

withMisfireHandlingInstructionIgnoreMisfires

——以错过的第一个频率时间立刻开始执行

——重做错过的所有频率周期

——当下一次触发频率发生时间大于当前时间以后,按照Interval的依次执行剩下的频率

——共执行RepeatCount+1次

withMisfireHandlingInstructionNextWithExistingCount

——不触发立即执行

——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数

——以startTime为基准计算周期频率,并得到FinalTime

——即使中间出现pause,resume以后保持FinalTime时间不变

withMisfireHandlingInstructionNowWithExistingCount

——以当前时间为触发频率立即触发执行

——执行至FinalTIme的剩余周期次数

——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到

——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值

withMisfireHandlingInstructionNextWithRemainingCount

——不触发立即执行

——等待下次触发频率周期时刻,执行至FinalTime的剩余周期次数

——以startTime为基准计算周期频率,并得到FinalTime

——即使中间出现pause,resume以后保持FinalTime时间不变

withMisfireHandlingInstructionNowWithRemainingCount

——以当前时间为触发频率立即触发执行

——执行至FinalTIme的剩余周期次数

——以调度或恢复调度的时刻为基准的周期频率,FinalTime根据剩余次数和当前时间计算得到

——调整后的FinalTime会略大于根据starttime计算的到的FinalTime值

MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT

——此指令导致trigger忘记原始设置的starttime和repeat-count

——触发器的repeat-count将被设置为剩余的次数

——这样会导致后面无法获得原始设定的starttime和repeat-count值

问题:想要实现调度的启动和暂停以及恢复功能,但是暂停遇到问题
暂停后重新启动,会连续多次调用job中的execute方法。如果当前工作的处理时间过长必然会导致问题。

答案:

1
misfireInstruction = CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING
2
quartz.properties
#这个时间大于10000(10秒)会导致MISFIRE_INSTRUCTION_DO_NOTHING不起作用。
org.quartz.jobStore.misfireThreshold = 5000

代码:

public String add() throws IOException, SchedulerException
{// 一定要紧跟Validate之后写验证结果类
String seconds = job.getCronExpression();
//String cronExp = "0/" + seconds + " * * * * ?";
String cronExp = seconds;
job.setCronExpression(cronExp);
Scheduler scheduler = schedulerFactoryBean.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());

// 获取trigger,即在spring配置文件中定义的 bean id="myTrigger"
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

// 不存在,创建一个
if (null == trigger) {
JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class)
.withIdentity(job.getJobName(), job.getJobGroup()).build();
jobDetail.getJobDataMap().put("scheduleJob", job);

// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

// 按新的cronExpression表达式构建一个新的trigger
trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
.withSchedule(scheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();
System.out.println("trigger.getMisfireInstruction() = "+trigger.getMisfireInstruction());
scheduler.scheduleJob(jobDetail, trigger);
} else {
// Trigger已存在,那么更新相应的定时设置
// 表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());

// 按新的cronExpression表达式重新构建trigger
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();
System.out.println("trigger.getMisfireInstruction() = "+trigger.getMisfireInstruction());
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(triggerKey, trigger);
}

return SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  quartz