调度(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值
设置触发器的错误策略
/** * 创建定时任务 */ public static void createScheduleJob(Scheduler scheduler, SysJob job) { try { //构建job信息 JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build(); //表达式调度构建器 CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression()); cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder); //按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId())) .withSchedule(cronScheduleBuilder).build(); //放入参数,运行时的方法可以获取 jobDetail.getJobDataMap().put(ScheduleJobConstant.TASK_PROPERTIES, job); //执行器添加 定时任务(自动存入数据库) scheduler.scheduleJob(jobDetail, trigger); //暂停任务 if (job.getStatus().equals(ScheduleJobConstant.Status.PAUSE.getValue())) { pauseJob(scheduler, job.getJobId()); } } catch (Exception e) { log.error("createScheduleJob 异常:", e); } } /** * 表达式与触发器构建 * @param job * @param cb * @return * @throws Exception */ public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb) throws Exception { switch (job.getMisfirePolicy()) { case ScheduleJobConstant.MISFIRE_DEFAULT: return cb; case ScheduleJobConstant.MISFIRE_IGNORE_MISFIRES: //不触发立即执行 //——等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 return cb.withMisfireHandlingInstructionIgnoreMisfires(); case ScheduleJobConstant.MISFIRE_FIRE_AND_PROCEED: //以错过的第一个频率时间立刻开始执行 //——重做错过的所有频率周期后 //——当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 return cb.withMisfireHandlingInstructionFireAndProceed(); case ScheduleJobConstant.MISFIRE_DO_NOTHING: // 不触发立即执行 // 等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 return cb.withMisfireHandlingInstructionDoNothing(); default: throw new Exception("The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks"); } }
部分内容摘录自: