版本:quartz 2.2.3
环境:2台linux机器搭建集群
问题现象:1个10s循环执行的job,每隔10s会同时在2台机器进行调度执行。
问题分析过程:首先baidu了一些网上类似问题,有些是单点出现重复执行的,跟本问题现象不一样;还有些集群出现的重复执行问题,给出的解决思路是自己另外写一个表加数据库锁或者分布式锁或者一致性工具zookeeper,通过这些手段来保证一致性。个人感觉quartz已经开源很久,这是个基本问题,应该是配置或环境哪里不对。继续分析,将job的执行结果和执行时间保存输出后发现一个现象.
recordid | jobid | runtime |
2248 | 001 | 20180319151420 |
2247 | 001 | 20180319151419 |
2246 | 001 | 20180319151410 |
2245 | 001 | 20180319151409 |
同一个任务有间隔10s的,有间隔1s执行的。间隔1s的是2台机器同时执行的,差1s是这2个机器有时间差。确认了一下,这2台机器没有进行时间同步。感觉问题就在这里。赶紧搜索了一下,确实有人提到集群机器应该保持时间同步,但没有说为什么。实验一下,配置了ntp服务同步时间后,发现问题确实消失了,job不会重复执行了。那么为什么会出现这种情况呢?看看代码
quartz工作机制:网上有很多文章进行介绍,这里只说与本文相关的重点。QuartzSchedulerThread这个类的职责就是不断的去获取即将要执行的triggers,然后执行它们。
/**
* <p>
* The main processing loop of the <code>QuartzSchedulerThread</code>.
* </p>
*/
@Override
public void run() {
boolean lastAcquireFailed = false;
while (!halted.get