SpringBoot启动Quartz集群报找不到Trigger记录的Misfire错误
Quartz集群启动时Misfire处理报找不到Trigger记录的解决方案
问题根因
这个报错是集群模式下Quartz多线程并行操作的时序不一致导致的,触发链路如下:
- 启动监听方法加了
@Async注解,业务侧调度单次任务的逻辑和Quartz自身的Misfire扫描、任务调度流程完全并行执行 - 业务代码创建的是
startAt(new Date())的立即执行单次任务,Trigger记录写入QRTZ_TRIGGERS、QRTZ_SIMPLE_TRIGGERS表后,会被调度线程立刻捞取执行,执行完成后Quartz会自动删除这两张表中对应单次任务的记录(repeatCount=0的任务执行完无留存) - MisfireHandler轮询扫错过执行时间的任务时,刚好在任务删除前从
QRTZ_TRIGGERS表读到了该Trigger的记录,等它再去QRTZ_SIMPLE_TRIGGERS查详情时,调度线程已经把关联记录删完了,就会抛出找不到记录的异常 - 配置中
misfireThreshold=60000(1分钟阈值)、集群节点启动时间差、业务分布式锁不控制Quartz内部线程启动时机,都会放大这个问题的出现概率。
这个异常本身不影响业务逻辑,既不会导致任务漏执行,也不会造成数据脏写,只是会打印错误日志。
修复方案
按优先级从高到低选择即可:
- 调整Quartz启动时序,从根源上避免并行冲突
配置Spring Boot关闭Quartz自动启动:
把init方法上的spring.quartz.auto-startup=false@Async注解去掉,在init方法内所有业务逻辑、任务调度操作全部完成后,手动启动Quartz调度器:@EventListener(ApplicationReadyEvent.class) @DLockAcquired(keyName = "datasource-init") public void init() { logger.info("Initialize Synchronize datasource on startup ..."); try { this.doSyncDatasource(); } catch (Exception e) { logger.error("Initialize datasource failed, error: ", e); } aferInitialize.set(true); // 所有任务调度完成后再启动Quartz schedulerFactoryBean.getScheduler().start(); } - 优化单次任务的Trigger配置,降低时序冲突概率
给立即执行的单次任务留少量启动缓冲,同时显式配置misfire忽略策略,避免已删除的任务进入misfire处理流程:public void scheduleJobOnce(JobDetail jobDetail, TriggerKey triggerKey) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); Trigger simpleTrigger = TriggerBuilder.newTrigger() // 留1.5s缓冲,避免刚写入就被判定为misfire .startAt(new Date(System.currentTimeMillis() + 1500)) .withIdentity(triggerKey) .withSchedule(SimpleScheduleBuilder.simpleSchedule() .withRepeatCount(0) // 单次任务错过触发直接丢弃,不走misfire恢复 .withMisfireHandlingInstructionIgnoreMisfires() ).build(); try { scheduler.scheduleJob(jobDetail, simpleTrigger); } catch (SchedulerException e) { logger.error("Quartz schedule job failed, {}.", JsonUtil.parseObjectToString(jobDetail.getJobDataMap()), e); throw e; } } - 兜底容错处理
如果不想调整现有逻辑,可以继承LocalDataSourceJobStore重写recoverMisfiredJobs方法,捕获Trigger找不到的异常,打debug日志后直接跳过,不要抛出错误日志即可。
内容的提问来源于stack exchange,提问作者leo.li
相关产品推荐
相关产品推荐

