背景
在测试是Quartz调度任务时,有时会遇到修改服务器系统时间来实现任务重跑的效果。然而,这样并没什么卵用。现象是:怎么任务还没有触发,没有触发。。。然后,只能宠重启web服务器,然后就奇迹般的依据预定的时间触发了。
刨根问底:意识到Quartz将任务job信息进行缓存。导致,无论你改任务参数,打偶无法达到动态修改job的目的。
这几天有时间发刊Quartz源码并结合晚上已有的资料进行了梳理。
参见资料:http://blog.itpub.net/11627468/viewspace-1763498/
版本信息:org.quartz-scheduler-2.2.3
调度触发由trigger开始。如下图:
原理分析
然后,依据轮询线程QuartzSchedulerThread进行轮询。从RAMJobStore中获取下一个可执行job。这里的RAMJobStore即使job的内存缓存容器。是在QuartzScheduler构造函数中初始化的。
QuartzSchedulerThread的run方法就是关键所在,去获得下一个可执行job。
跟进去看到,RAMJobStore会与job集合中的getNextFireTime判断,如下:
问题:
job执行后,如何去更新下次点火时间的?
代码回到QuartzSchedulerThread的run方法中,看到如下一段代码:
进入CronTriggerImpl看到真相啦。
至此,了解了job每次“点火”成功后都会更新下次点火时间。这就是为什么,将服务时间修改未过去时间,操了cron表达式指定的时间,无法出发job的原
问题:如何实现动态的修改cron表达式?
简单思路
从内存jobStore中取出,trigger信息。然后更新相关出发参数。
实现代码:
1 | @Service |
测试代码
1 | @RunWith(SpringJUnit4ClassRunner.class) |