Spring quartz 集群模式下trigger_state error问题原因

问题描述


在项目中采用了Spring quartz调度任务来执行定时任务,quartz本身是支持集群化方式的,可以配置一个数据源,quartz会在数据库中创建一系列的表,使用这些表来存储调度的信息,集群中所有的节点都访问这一个数据库,这样可以实现集群环境下的定时任务调度。

但是在最近生产环境出现了这样的问题,新增的一个定时调度任务,当服务启动后,执行两次以后,该任务就不再执行了,但是其他原有的定时任务并没有出现问题,只有这个新增的任务无法执行,检查qrtz_triggers表,发现该条调度任务的记录的trigger_state变成了”error”状态。

 

问题分析


1、检查是否新增的定时任务抛出异常,导致了任务中断,加入大量的日志以及异常捕获,未发现任何异常的日志,排除了代码报错的可能

2、猜测是否是因为数据库中调度相关表存在脏数据,导致了新增的调度任务不执行;随后将相关表全部清空,重启集群中所有节点,观察,发现仍然是执行两次后变为”error”

3、检查qrtz_scheduler_state表,发现存在多条记录,根据网上查找的信息,将多条记录删除,只保留一条,再重启集群,观察,发现仍然不行

4、由第三条可知,qrtz_scheduler_state表中有多条记录,仔细观察instance_name的记录,发现是由服务器节点的实例名加数字组成,将instance的地址与集群中每个节点进行对比,发现问题原因,有两个instance的id并不在生成环境的集群节点中,但是与集群公用一个数据库,那两个节点的代码版本,发现与当前线上版本不一致,没有新增的定时调度任务,由此导致了该问题的发生

 

问题总结


当使用quartz集群模式时,当集群中的代码版本不一致,会出现qrtz_triggers中trigger_state的状态变为”error”的情况,原因是集群模式先quartz执行调度任务,是根据数据库表中的调度记录进行执行,当执行到有对应代码的节点上,不会出现问题,但是当执行到没有对应代码的节点上,就会变为”error”,
因此在集群环境下,节点较多的时候使用quartz,需要注意每个节点的代码版本一定要保持一致
 

提供的引用内容未提及Quartz框架中TRIGGER_STATE字段的取值相关信息。在Quartz框架里,TRIGGER_STATE字段一般有以下常见取值: - **WAITING**:触发器处于等待触发的状态,正等待着触发时间的到来。 - **ACQUIRED**:触发器已被调度器获取,正在准备执行。 - **EXECUTING**:触发器对应的任务正在执行。 - **COMPLETE**:触发器对应的任务已经执行完成。 - **BLOCKED**:触发器对应的任务由于某些原因被阻塞,暂时无法执行。 - **ERROR**:触发器在执行过程中出现了错误。 - **PAUSED**:触发器被暂停,不会触发任务。 - **PAUSED_BLOCKED**:触发器处于暂停状态,并且其对应的任务也被阻塞。 以下是一个简单的示例代码,展示如何获取触发器状态: ```java import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; import org.quartz.TriggerKey; import org.quartz.impl.StdSchedulerFactory; public class TriggerStateExample { public static void main(String[] args) { try { // 获取调度器实例 Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); // 定义触发器键 TriggerKey triggerKey = new TriggerKey("myTrigger", "myTriggerGroup"); // 获取触发器 Trigger trigger = scheduler.getTrigger(triggerKey); // 获取触发器状态 Trigger.TriggerState triggerState = scheduler.getTriggerState(triggerKey); System.out.println("Trigger State: " + triggerState.name()); // 关闭调度器 scheduler.shutdown(); } catch (SchedulerException e) { e.printStackTrace(); } } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值