调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则
quartz 暂停后重新启动,在暂停时 被暂停后的任务,在启动后会补偿执行即 会连续多次调用job中的execute方法。
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方法。如果当前工作的处理时间过长必然会导致问题。
答案:
CronScheduleBuilder ScheduleBuilder = CronScheduleBuilder.cronSchedule(annotation.cronExp());
/**
* ScheduleBuilder.withMisfireHandlingInstructionDoNothing()
* 不触发立即执行————等待下次Cron触发频率到达时刻开始按照Cron频率依次执行
*/
CronTrigger trigger = TriggerBuilder.newTrigger().forJob(build).withIdentity(annotation.name()).withSchedule(ScheduleBuilder.withMisfireHandlingInstructionDoNothing()).build();
注: ScheduleBuilder.withMisfireHandlingInstructionDoNothing()
quartz.properties
#这个时间大于10000(10秒)会导致MISFIRE_INSTRUCTION_DO_NOTHING不起作用。
org.quartz.jobStore.misfireThreshold = 5000
#配置quartz
quartz:
job-store-type: jdbc
#相关属性配置
properties:
org:
quartz:
scheduler:
# 调度标识名 集群中每一个实例都必须使用相同的名称 (区分特定的调度器实例)
instanceName: clusteredScheduler
# ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)
instanceId: AUTO
jobStore:
# 数据保存方式为持久化
class: org.quartz.impl.jdbcjobstore.JobStoreTX
#
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 表的前缀
tablePrefix: QRTZ_
# 加入集群 true 为集群 false不是集群
isClustered: true
# 调度实例失效的检查时间间隔
clusterCheckinInterval: 10000
# 设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
useProperties: false
#这个时间大于10000(10秒)会导致MISFIRE_INSTRUCTION_DO_NOTHING不起作用。
misfireThreshold: 5000
threadPool:
class: org.quartz.simpl.SimpleThreadPool
# 并发个数
threadCount: 10
# 优先级 (threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1)
threadPriority: 5
# 自创建父线程
threadsInheritContextClassLoaderOfInitializingThread: true