概念理解
misfire顾名思义, 就是quartz在应该触发trigger的时候未能及时将其触发( 原因可能是线程池没有线程可用 ), 这将导致trigger的下次触发时间落在在当前时间之前, 那么按照正常的quartz调度流程, 该trigger就再没有机会被调度了. 由于一个调度器实例在每次调度过程中都会有一定的睡眠时间, 所以存在一段时间内所有调度器实例都在睡眠, 这也会使trigger不能被及时触发. 因此调度器需要每隔一段时间( 15s ~ 60s )查看一次各个trigger的nextfiretime( 即下次触发的时间 ), 检查出是否有trigger的下次触发时间落在当前时间之前足够长的时间, 在这里系统设定了一个60s的域( misfireThreshold ), 当一个trigger下一次触发时间早于当前时间60s之外, 调度器判定该触发器misfire. 为了在发现触发器misfire之后启动相应的流程恢复trigger至正常的状态, quartz在trigger中可设置相应的策略.
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值