天天看点

集群环境下,谁偷走quartz配置的定时任务

错误现象:

在本地开发环境中,应用服务启动后trigger_state直接就变为error

 前段时间在项目中,使用quartz配置一个定时任务,定时任务都持久化到oracle数据库中,但是应用服务器启动后,数据库qrtz_triggers(trigger信息表)中,对应的任务数据的trigger_state字段就直接变为error,导致定时任务不执行。

没有错误log日志,出错原因难定位。

对以下可能出错的原因进行了调查:

1.quartz文件配置错误

  ① 检查配置文件,调查结果是,配置文件没有发现错误。

  ② 项目中已经配置有一条定时任务a,但是任务a能正常执行。

  ③ 将任务a的quartz配置注释,只留下新增配置的定时任务,启动后还是一样报错。

项目中,其他子系统也使用了quartz配置定时任务,可以排除不是quartz配置文件错误。

2.定时任务实现类出错

  ① 定时任务实现类中,将业务逻辑全部注释,只输出system.out.println,但启动后,也报错。(经过很多次的调试,有时应用服务器启动,也能正常的执行一次新增的定时任务,但后面trigger_state就又变为error)

  ② 将新增的定时任务配置的时间,由2分钟改为10秒后,定时任务能正常运行。

3.发现数据库qrtz_scheduler_state(调度器状态表)中,有很多条数据。表示有很多实例应用都在运行quartz。

经过这些测试和调查,发现是其它机器可能将新增的定时任务取走执行,但是其它机器上又没有配置该新增定时任务,然后再调度该任务的时候就将数据库qrtz_triggers(trigger信息表)中,对应的任务数据的trigger_state字段变为error。

综上所述,本地开发环境下,项目组成员使用同一数据库进行开发时,每位开发人员在quartz中,配置的定时任务数量不一致。当应用服务启动后,quartz任务调度器会根据数据库qrtz_triggers(trigger信息表)中的数据执行job,数据库中已经存在新增的定时任务,而取走的应用服务quartz配置中并没有配置该新增定时任务,执行时就将trigger_state变为error,导致新增job不能正常执行。

建议:

使用quartz配置定时任务,多台服务器使用同一数据库进行开发时,保证数据库qrtz_scheduler_state(任务调度表)中只有一条数据,这样就能保证定时任务是自己的应用服务取走执行的。