当应用服务器从单机扩展至多台-集群模式时,这种情况下,原有的简单配置的定时任务调度方案肯定就行不通了。因为大多数定时任务都不具备幂等性,我们的预期一定也是在某一时刻触发定时任务执行一次,而不是多次。
我们需要调整对Quarzt的集群控制,解决多台服务器并行运行同一个定时任务的问题。
主要思路:将JOB信息维护在DB里,使用标志位来控制(如enable=Y/N,“Y”表示使用中,“N”表示空闲)。应用节点上触发某个JOB执行时,先查询DB中该JOB的状态:没有运行,更新状态为运行中,再开始执行;否则,跳过。
过程/步骤:
- 检查Job是否在运行中(此处可以通过函数或过程来实现)
- 根据jobname、enable字段查找Job:(select job_id from job_config where job_id = (select job_id from job_define where job_name = #param.JobName#) for update nowait)
- 再根据job_id和enable='N'去更新config记录,如果更新结果SQL%ROWCOUNT = 0 说明Job已经在运行中了,否则就是正常更新逻辑。
- 返回更新前job的状态,提交事务
思考:
做完以上调整基本上已实现Quartz的集群控制,思考另外一个问题,“Job执行异常中断时,没有更新Job状态为空闲状态,这样此job以后再也没法触发 了”--
--可以从检查Job是否运行中的逻辑入手,前提所有的Job运行时长的边界能明确界定