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

osc_xoak61wg 2021-01-21 11:43:12
spring Quartz wrapper jprofiler


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

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

分析1 怀疑是代码问题?

 对众帮文件上传定时任务代码进行排查 并无发现编码问题,并且对1月7号上的版本 和上一个版本进行代码比对 并未发现对众邦的代码有所改动的地方

分析2 项目定时任务框架 spring quartz 内部任务存储 调度问题?

 Quartz 是基于RAMJobStore调度中心去调度的,里面有Job(任务),Trigger(触发器)。
通过对项目定时任务代码的了解 及源码的分析 得知:

项目启动时 会把applicationContext-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秒,并且做了一个定时任务计数器。
“fpcCallBack”:205,
“alipayPromoteDataAndRule”:1657,
“bdTransactionCallBack”:680,
“networkVerifyDataAndRule”:5,
“processDataAndRule”:976,
“paphLoanDataAndRule”:203,
“fplCallBack”:124,
“jdDataAndRule”:828,
“paphDataAndRule”:312,
“callBack”:511,
“fpShareLoanPeople”:1260,
“fpcDataAndRule”:1282,
“wsdMigrateCreditAckDate”:9,
“zhongbangFileUp2View”:“1”,
“sendTxnJob”:“1”,
“AliPayBigTextAnalysis”:393,
“pplDataAndRule”:33,
“sendTxnBdCreditMigrate”:18,
“blackList”:46,
“sendTxnJDLoan”:15,
“creditCallBack”:1312,
“fileSyncDataAndRule”:1529,
“ppcDataAndRule”:127,
“jLFSCallBack”:62,
“qlLoanDataAndRule”:2,
“OpenAccountNetCheck”:54,
“zbCallBack”:3,
“yjSendTxnLoan”:5,
“gjjCallBack”:101,
“ppdDataAndRule”:82,
“alipayDataAndRule”:1687,
“jfDataAndRule”:506,
“jfCallBack”:17,
“qlLoanCallBack”:2,
“bdCreditDataAndRule”:4966,
“alipayHBDataAndRule”:1673,
“fileSyncCallBack”:3123,
“youXLoanDataAndRule”:6,
“pplCallBack”:4,
“bdCreditCallBack”:794,
“wsdConfirmDataAndRule”:12,
“bdAdjustLimitMigrate”:3045,
“sendSoapJob”:1102,
“OdMonitor”:1321,
“estDateSourceMonitor”:25,
“qianLLCallBack”:4,
“yxCallBack”:“1”,
“jLFSDataAndRule”:605,
“zbDataAndRule”:2,
“cxcDataAndRule”:535,
“bdTransactionDataAndRule”:3224,
“bdAdjustmentCallBack”:1020,
“fileUpload”:678,
“bdCreditMigrate”:2043,
“yxLoanDataAndRule”:6,
“sendTxnLoan”:11,
“ppcCallBack”:9,
“wsdDataAndRule”:10,
“dfCallBack”:477,
“cxlDataAndRule”:475,
“gjjDataAndRule”:725,
“qianLLoanDataAndRule”:519,
“qlCallBack”:“1”,
“fileDownloadAndUpBD”:386,
“tszCallBack”:“1”,
“tszDataAndRule”:“1”,
“yxDataAndRule”:6,
“bdAdjustmentDataAndRule”:6760,
“yjDataAndRule”:8,
“jdCallBack”:1153,
“bdTransactionMigrate”:1913,
“wsdMigrateCreditDate”:9,
“yjFileSyncDataAndRule”:8,
“fplDataAndRule”:1308









































































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

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

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

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

**

问题解决:

那么此时留下的问题就是 解决 quartz执行线程数量太少10个的问题
我们要做的就是 增加quartz 执行线程数量
由于本项目 quartz 的框架版本过低1.5.2 无法通过quartz.properties
进行声明线程数量 这里我就不想吐槽了 试了很多种办法不行 ,而且版本调整到2.0.0以上后 OPS 封装的quarzt代码全部报错 版本完全不兼容。
于是我们在applicationContext-quartz.xml中
在这里插入图片描述
在SchedulerFactoryBean中对quartz.properties进行复写 并且改变线程数量为100,以及Trigger检查器 默认每次只Acquire一个Trigger。





丢到测试环境测试 定时任务计数器打印结果如下:
“bdCreditDataAndRule”:128,
“fpShareLoanPeople”:14,
“gjjCallBack”:14,
“youXLoanDataAndRule”:16,
“jdCallBack”:15,
“jfCallBack”:31,
“bdAdjustLimitMigrate”:30,
“sendTxnJDLoan”:32,
“pplDataAndRule”:15,
“estDateSourceMonitor”:“1”,
“fplDataAndRule”:11,
“wsdMigrateCreditDate”:9,
“creditCallBack”:7,
“paphDataAndRule”:10,
“tszDataAndRule”:12,
“ppdDataAndRule”:51,
“wsdMigrateCreditAckDate”:19,
“dfCallBack”:10,
“yxLoanDataAndRule”:43,
“zhongbangFileUp2View”:2,
“qianLLoanDataAndRule”:11,
“fpcDataAndRule”:12,
“callBack”:9,
“paphLoanDataAndRule”:11,
“pplCallBack”:11,
“blackList”:2,
“yjSendTxnLoan”:39,
“ppcDataAndRule”:20,
“cxlDataAndRule”:10,
“yxLoanCallBack”:14,
“gjjDataAndRule”:23,
“processDataAndRule”:19,
“sendTxnLoan”:37,
“ppcCallBack”:15,
“alipayPromoteDataAndRule”:8,
“qlLoanCallBack”:8,
“qlCallBack”:6,
“bdTransactionDataAndRule”:129,
“qlDataAndRule”:8,
“fileSyncCallBack”:156,
“plagueMonitor”:2,
“yjFileSyncDataAndRule”:49,
“fplCallBack”:10,
“bdAdjustmentCallBack”:19,
“bdAdjustmentDataAndRule”:149,
“sendTxnBdCreditMigrate”:39,
“bdCreditCallBack”:14,“fpcCallBack”:9,
“bdTransactionMigrate”:35,
“yjDataAndRule”:39,
“cxcDataAndRule”:14,
“bdTransactionCallBack”:24,
“sendSoapJob”:22,
“fileDownloadAndUpBD”:24,
“alipayDataAndRule”:8,
“OpenAccountNetCheck”:3,
“fileUpload”:7,
“AliPayBigTextAnalysis”:11,
“qlLoanDataAndRule”:14,
“jfDataAndRule”:10,
“qianLLCallBack”:24,
“bdCreditMigrate”:35,
“alipayHBDataAndRule”:13,
“wsdDataAndRule”:38,
“jdDataAndRule”:15,
“yxDataAndRule”:8,
“sendTxnJob”:19,
“wsdConfirmDataAndRule”:37,
“yxCallBack”:10,
“OdMonitor”:14,
“fileSyncDataAndRule”:36,
“zbCallBack”:15,
“tszCallBack”:11,
jLFSDataAndRule":13,
“jLFSCallBack”:9,
“zbDataAndRule”:39










































































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

quartz定时任务使用结论

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



版权声明
本文为[osc_xoak61wg]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4276902/blog/4917442

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云