Quartz的misfire策略学习

时间:2021-01-31 21:59:07

上一篇中讲了在项目中简单使用Quartz,其中有一点是看博客时注意到的,虽然项目中实际不太可能出现misfire的情况,但还是初步了解了下。


Quartz中有一种job接口,是StatefulJob,有状态任务,简单来说,这种job使用在不能并发执行的场景下。比如定义了某个任务,每分钟执行一次,对一些数据进行增删操作,正常执行时,每分钟执行的job互不影响,但某个时刻出现了意外,某个任务执行了三分钟。那么,在这个任务持续执行的过程中,我们是不希望并发执行另外两次“例行”任务的,这就需要使用有状态任务,而没有执行的两次任务就是misfired job。


对于判定为misfired job,其实有很多条件,目前了解到的有:

0. 到执行时间时,上一个任务还未完成;

1. 过期时间已超过设置的misfireThreshold;

2.1. 线程池中已没有空闲线程

2.2. 线程池中虽有空闲线程,但有优先级更高的任务


产生misfire后,会根据设置的misfire策略进行任务的处理。


对CronTrigger来说,有三种misfire策略:

Quartz的misfire策略学习

MISFIRE_INSTRUCTION_SMART_POLICY = 0


Quartz的misfire策略学习

MISFIRE_INSTRUCTION_FIRE_ONCE_NOW = 1

MISFIRE_INSTRUCTION_DO_NOTHING = 2


MISFIRE_INSTRUCTION_SMART_POLICY是默认的策略,从字面意思去理解,应该是会自动选择具体的trigger实现类中的具体策略吧,没有详细的了解。

MISFIRE_INSTRUCTION_FIRE_ONCE_NOW是立即触发一次,触发后恢复正常的频率。

MISFIRE_INSTRUCTION_DO_NOTHING是什么都不做,继续等下一次预定时间再触发。


对SimpleTrigger有更多种策略:

Quartz的misfire策略学习

因为用Cron就基本满足各种各样的触发配置,所以对Simple基本没做过多的了解


以我做的项目来说,使用DO_NOTHING就可以满足情况了,就是说,即使产生了misfired job,那在上一个job全部执行完后,什么都不要做,等下一个触发时间到了的时候,再照常执行就可以了。所以在配置中使用了这种misfire策略,就是在CronTriggerBean中配置了:<property name="misfireInstruction" value="2" />


参考资料:

https://www.ibm.com/developerworks/cn/opensource/os-cn-quartz/

http://www.cnblogs.com/pzy4447/p/5201674.html

http://blog.sina.com.cn/s/blog_56d8ea900101eu45.html

https://dzone.com/articles/quartz-scheduler-misfire

http://www.aichengxu.com/java/6569538.htm

http://blog.csdn.net/george_hsu/article/details/6943336