Springboot-1.5.x+Quartz-2.x 循环任务有些时间点不执行?

本文讨论了在Springboot 1.5.x版本中使用Quartz 2.x时遇到的循环任务在特定时间点未执行的问题。经过后台源码调试,找到了问题原因,并提供了修复配置示例,帮助读者解决类似问题。
摘要由CSDN通过智能技术生成

具体情况:

Sprinboot-1.x + Quartz-2.x + Java 1.8,设定了Cron表达式为“0 0/3 10-22 * * ?”,即每隔3分钟运行一次任务。
实际运行时,会偶尔有时间点不执行,比如:
10:30, 10:33, 10:36,10:42,10:51,11:00,11:03,11:06,11:15,11:21,11:24.......
执行的任务本身只需要 10 秒左右就能执行完的,因此不存在任务执行时间过长问题。
Quartz也没打印警告或异常信息。


尝试过如下方式无效果:

1. 清空数据库现存的计划任务数据,重新设定计划任务;
2. 修改 org.quartz.jobStore.misfireThreshold = 60000 或 1800000 或 3600000 或 0;
3. 将间隔由 每隔3分钟 改为每隔 15 分钟,那么基本每次都执行,但总时间一长还是会发生跳过的情况;


后台经过同事直接调试源码,得出如下结论:

Quartz 会在你的定时任务执行前后,都进行加锁操作,这些操作有时耗时会过长,而这些时间是算在定时任务里面的。


最终修改的配置参数为下列三个:

# 在调度程序处于空闲状态时,调度程序将在重新查询可用触发器之前等待的时间量(以毫秒为单位),默认是30秒
org.quartz.scheduler.idleWaitTime=300000

# 这个属性???(默认 60000)
org.quartz.jobStore.misfireThreshold = 10000

# 当 org.quartz.scheduler.batchTriggerAcquisitionMaxCount >1 
# 并且 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 下面参数 必须设为 true
org.quartz.jobStore.acquireTriggersWithinLock=true 

 

已修复的示例配置:

# 固定前缀org.quartz
# 主要分为scheduler、threadPool、jobStore、plugin等部分
#

# 设置调度器的实例名(instanceName) 和实例ID (instanceId)
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
#如果使用集群,instanceId必须唯一,设置成AUTO
#org.quartz.scheduler.instanceId = AUTO

org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false

# 在调度程序处于空闲状态时,调度程序将在重新查询可用触发器之前等待的时间量(以毫秒为单位),默认是30秒
org.quartz.scheduler.idleWaitTime=300000
# 允许调度程序节点一次获取(用于触发)的触发器的最大数量,默认是1
org.quartz.scheduler.batchTriggerAcquisitionMaxCount=1
# 允许触发器在其预定的火灾时间之前被获取和触发的时间(毫秒)的时间量,默认是0
org.quartz.scheduler.batchTriggerAcquisitionFireAheadTimeWindow=0

# 实例化ThreadPool时,使用的线程类为SimpleThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool

# 并发个数
org.quartz.threadPool.threadCount = 10
# 优先级(最大值10,最小值1,常用值5)
org.quartz.threadPool.threadPriority = 5
# 加载任务代码的ClassLoader是否从外部继承
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
# 这个属性???(默认 60000)
org.quartz.jobStore.misfireThreshold = 10000
# 当 org.quartz.scheduler.batchTriggerAcquisitionMaxCount >1 
# 并且 org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 下面参数 必须设为 true
org.quartz.jobStore.acquireTriggersWithinLock=true 

# 默认存储在内存中
#org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore

# 持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_

org.quartz.jobStore.dataSource = myDS
org.quartz.dataSource.myDS.connectionProvider.class:com.hsbc.gbm.hss.chinacustody.filemonitoring.scheduler.DruidForQuartzConfiguration

Springboot1.x配置Quartz的后台代码:

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

/* @formatter:off
 * @DisallowConcurrentExecution 
 * 禁止并发执行多个相同定义的JobDetail, 注解是加在Job类上的, 
 * 但意思并不是不能同时执行多个Job, 而是不能并发执行同一个Job Definition(由JobDetail定义), 
 * 但是可以同时执行多个不同的JobDe
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值