spring quartz 部分定时任务不执行问题定位修复方案

您所在的位置:网站首页 定时任务执行失败 spring quartz 部分定时任务不执行问题定位修复方案

spring quartz 部分定时任务不执行问题定位修复方案

2024-07-11 10:43| 来源: 网络整理| 查看: 265

Quartz部分定时任务不执行问题分析过程及修复方案

背景: 2021年1月7号上线迁移需求之后,出现最为明显的 文件上传 其他部分定时任务也不执行的情况 执行时间并没有按照约定时间去执行

分析1 怀疑是代码问题? 对文件上传定时任务代码进行排查 并无发现编码问题,并且对1月7号上的版本 和上一个版本进行代码比对 并未发现对众邦的代码有所改动的地方 分析2 项目定时任务框架 spring quartz 内部任务存储 调度问题? Quartz 是基于RAMJobStore调度中心去调度的,里面有Job(任务),Trigger(触发器)。 通过对项目定时任务代码的了解 及源码的分析 得知:

项目启动时 会把quartz.xml配置文件中的所有定时任务加载到jobDefinitions 这个队列中,遍历jobDefinitions 把每个定时任务的 job 和 Trigger获取到,通过Quartz API 把定时任务添加到RAMJobStore, 经过对jobDetail的校验 ,这里主要是校验name,group,jobClass 是否为空,然后jobDetail的下次触发时间是否合法 然后添加到RAMJobStore(JobWrapper, TriggerWrapper)中。 秉着这一逻辑思想 1月14号上线 项目重启后 拉取项目 堆栈包heap1.hprof 使用jprofiler分析工具 打开heap1.hprof 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 如图 找到RAMJobStore中的两个存储对象 发现job 和 trigger中存储的数量是一致的,于是我打算点对点的排查 由于生产最为明显的是众帮文件上传定时任务不执行 所以我从这76任务中,找到众帮文件上传的wrapper 看看是不是有什么问题。在这里插入图片描述 如图可以看出 文件上传的定时任务 从开始执行时间,下次触发时间,是否有配套的监听器 都是正常的 ,可就是不执行,于是我开始quartz调度的过程,如何调度的执行的。 几经翻查 发现quertz 定时任务在调度时,都需要初始化一个线程池SimpleThreadPool 而这个线程池大小默认是10,而quertz任务触发调度的原则是: 1、线程池资源获取等待定时任务过期作废机制。 2、Quartz框架的定时任务执行是绝对时间触发的,所以存在“过期不候”的现象。

所以开始怀疑是项目定时任务过多87个 并且大部分定时任务都是 10秒 ,20秒,30秒 1分钟执行一次 过于密集

分析3 quartz 调度初始化没有问题 定时任务多,且时间密集导致?

为了复现和生产一样的情况 众帮及其他部分定时任务不执行的情况,由于测试环境基本没有数据,所以每个定时任务执行的非常快,所以不存在生产的情况,所以我把代码中每个定时任务 让他们执行时,都线程等待60秒,并且做了一个定时任务计数器。 “fpc######ck”:205, “ali######ule”:1657, “bdT######ack”:680, “net######ule”:5, “pro######ule”:976, “pap######ule”:203, “fp######ck”:124, “jd######ule”:828, “pa######ule”:312, “ca######k”:511, “fp######ple”:1260, “fp######le”:1282, “ws######ate”:9, “zhon######ew”:“1”, “sen######b”:“1”, “AliP######lysis”:393, “ppl######ule”:33, “se######igrate”:18, “b######List”:46, “se######an”:15, “cre######ck”:1312, “fil######ule”:1529, “p######ndRule”:127, “jL######ack”:62, “q######Rule”:2, “Op######etCheck”:54, “zb######ck”:3, “yj######oan”:5, “gjj######ack”:101, “ppd######ule”:82, “ali######ule”:1687, “jfDa######ule”:506, “jf######ack”:17, “ql######ack”:2, “bd######ule”:4966, “alip######ule”:1673, “file######ack”:3123, “you######ule”:6, “pp######ck”:4, “bd######ack”:794, “ws######ule”:12, “b######igrate”:3045, “se######pJob”:1102, “Od######itor”:1321, “est######onitor”:25, “qia######Back”:4, “yx######ack”:“1”, “jL######Rule”:605, “zb######dRule”:2, “cx######le”:535, “bd######le”:3224, “bd######ck”:1020, “fil######ad”:678, “bd######te”:2043, “yx######ndRule”:6, “sen######Loan”:11, “pp######Back”:9, “ws######ule”:10, “df######k”:477, “cxl######le”:475, “gjj######ule”:725, “qi######dRule”:519, “qlC######ack”:“1”, “file######BD”:386, “ts######ck”:“1”, “ts######dRule”:“1”, “yx######ule”:6, “bdA######dRule”:6760, “yjD######ule”:8, “jd######ck”:1153, “bd######rate”:1913, “ws######tDate”:9, “yj######AndRule”:8, “fpl######dRule”:1308

从计数器打印结果可以看出 在测试环境执行了15小时左右 果然出现了和生产一样的情况 一共87个定时任务 执行了73个有19个未执行 已执行的存在执行次数为个位数的情况

所以我认定quartz定时任务执行存在线程瓶颈 与此我发现为什么众帮的文件上传一次执行的机会都不能抢到吗?想必小伙伴们也会有这种猜疑 就算触发时间相同情况下 可触发的数量有限 难道zho******wJob 一次都抢不到执行线程吗?

于是 又一顿的百度 博客 终于找到了对应的解释 默认情况是触发时间先后顺序排列,触发时间比较前的先执行任务,但如果一个或多个任务同时在相同时间触发下,触发器设置优先级越高越先执行。如果优先级相同,则跟任务的存储方式有关,RAMJobStore时与TriggerKey排序有关,即按触发器名的字母序;如果是JdbcStore则跟数据库查询的默认排序有关了。Trigger优先级默认为5,数值越大优先级越高

这会大家应该明白了吧 众邦的定时任务名称叫做 zho******wJob 所以 在相同触发条件下 并且执行数量有限的情况下,他被淘汰了

**

问题解决:

那么此时留下的问题就是 解决 quartz执行线程数量太少10个的问题 我们要做的就是 增加quartz 执行线程数量 由于本项目 quartz 的框架版本过低1.5.2 无法通过quartz.properties 进行声明线程数量 这里我就不想吐槽了 试了很多种办法不行 ,而且版本调整到2.0.0以上后 系统封装的quarzt代码全部报错 版本完全不兼容。 于是我们在quartz.xml中 在这里插入图片描述

在SchedulerFactoryBean中对quartz.properties进行复写 并且改变线程数量为100,以及Trigger检查器 默认每次只Acquire一个Trigger。

丢到测试环境测试 定时任务计数器打印结果如下: “b######Rule”:128, “fp######eople”:14, “g######ck”:14, “you######Rule”:16, “jd######ack”:15, “jfC######ack”:31, “bdA######itMigrate”:30, “sen######DLoan”:32, “pplD######le”:15, “est######onitor”:“1”, “fp######le”:11, “ws######itDate”:9, “cr######lBack”:7, “pa######ndRule”:10, “tsz######ndRule”:12, “ppd######Rule”:51, “wsd######itAckDate”:19, “df######k”:10, “yx######dRule”:43, “zhon######Up2View”:2, “qian######dRule”:11, “fpc######Rule”:12, “cal######ck”:9, “pap######dRule”:11, “p######ck”:11, “bl######t”:2, “yjS######xnLoan”:39, “ppc######dRule”:20, “cxl######dRule”:10, “y######llBack”:14, “gj######dRule”:23, “proc######Rule”:19, “sen######oan”:37, “pp######ack”:15, “alip######dRule”:8, “qlLo######ack”:8, “ql######ack”:6, “bd######nDataAndRule”:129, “qlD######ule”:8, “file######lBack”:156, “pla######onitor”:2, “yjFil######taAndRule”:49, “fpl######ack”:10, “bdA######CallBack”:19, “bdAdjustm######aAndRule”:149, “sendT######tMigrate”:39, “bd######Back”:14,“fpcCallBack”:9, “bd######grate”:35, “yj######ule”:39, “cx######dRule”:14, “bdT######CallBack”:24, “send######pJob”:22, “fileD######UpBD”:24, “ali######ule”:8, “Open######Check”:3, “file######oad”:7, “A######xtAnalysis”:11, “qlL######aAndRule”:14, “jfDa######Rule”:10, “qi######allBack”:24, “bd######grate”:35, “alip######ndRule”:13, “wsdD######Rule”:38, “jdD######ule”:15, “yxD######Rule”:8, “sen######b”:19, “ws######dRule”:37, “yx######ck”:10, “Od######tor”:14, “file######ule”:36, “zb######ck”:15, “tsz######ack”:11, jLF######Rule":13, “jL######ack”:9, “zbD######Rule”:39

从结果中可以看出 每次定时任务都执行了,并且执行的次数都比较均匀,不像一开始 有的执行几千次,有的执行几十次,受线程执行数 已经定时任务首字木影响较大。 而且从结果中可以看出 众帮的数据处理执行了39次 众邦的文件上传 每10分钟执行一次 每次轮到执行的执行时,都执行了,不存在拿不到执行线程的情况

quartz定时任务使用结论

1、线程池资源获取等待定时任务过期作废机制。 2、Quartz框架的定时任务执行是绝对时间触发的,所以存在“过期不候”的现象。 3、在使用Quartzs框架时,一定要预先计算好triggers数量与线程池大小的匹配程度,资源一定要够,或者任务执行密度不能太大,否则等到线程任务释放完,trigger早已过期,就无法按预期时间触发了。 4、在进行业务代码开发过程中 尽量一个定时任务中处理多种业务代码,做异步线程处理,对定时任务进行归类 抽取 5.根据业务情况 不要一上来就增加定时任务,靠定时任务处理问题



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3