spring定时任务ThreadPoolTaskScheduler使用注意事项之线程池大小
背景
最近小伙伴解决了一个工单,描述为“手工推送案件无法推,提示token失效”,当前工单状态为待关闭,解决方案为“东软接口不稳定造成的,东软的接口恢复正常后,问题解决”,然后找现场让他们关闭工单,现场反馈:今天现场又出现相同的问题了!!!依然是token失效,工单关不了了。
过程
确认问题应用及版本
让对方把错误截图发了一下,发现好像不是卷宗自己的应用,跟卷宗团队小伙伴确认了一下,这是个定制的小工具。要到源码看了下,版本很干净,也不需要跟现场要版本号了,直接看当前代码即可。
问题初次定位
token失效有可能是服务器与客户端时差较大导致的,让现场核实了一下,就差几秒,不是这个原因。
让现场复现一下问题,并跟代码,发现所有请求东软接口的地方都需要在请求头传递token信息,而这个token是单例的,初次使用时会实例化。
现在既然找到token赋值的位置,且是单例的,现在又失效了,重启一下一定能解决,让现场重启
重启后确实解决了,从而得出结论“咱们只有在启动的时候申请了一次token,以后就再也没申请过,东软设置了token超时自动过期”,看看能不能让东软那边设置token永不过期
问题再次定位
但是!人家东软说token有效期是固定的两小时,且出问题的应用之前已经平稳运行好几天了。
基于目前的结论来看,每2个小时就需要重启一次应用才会避免token失效呀,现在的现象明显不是这样,怎么肥事?
继续找代码吧,看看都哪儿操作到token这个属性了,然后就找到了一个定时任务!
原来人家写了每半小时刷新一次token,而半个小时是小于东软的2小时的,所以理论上不会出现token失效的问题,那下一步的方向是哪儿呢?
定时任务嘛,看任务是否成功执行了就可以,反正他原来也有日志。
搜索了一遍之前的日志,没找到成功刷新的日志,这是怎么肥事?历史日志看不出来,咱们就看新日志吧。
到时间后为什么定时任务没执行?来,看代码,看日志!
代码里之前已经看到了,用的是spring提供的ThreadPoolTaskScheduler创建的定时器,没啥问题,看日志吧。
任务虽然执行成功了,但是日志有点儿怪呀,为什么刷新token的线程threadPoolTaskScheduler-1还被其他实例使用了?又不是主线程,他们应该是分别使用自己的才对呀,去SyncDataService看看。
哦哦,原来他们用的是同一个定时线程池的实例,扩散的看一下,原来有4个定时任务用的同一个实例。
那难道是他们在排队执行吗?去看一下ThreadPoolTaskScheduler的实现,网上说默认他只有一个工作线程,如果存在多个任务被触发时,会等第一个任务执行完毕才会执行下一个任务,看了下源码确实是这样。
回过头来看看日志是否可以佐证我们的猜想,11点41项目启动成功,定时任务实例化成功。
12点 SyncMaterials 任务开始执行(直接搜 threadPoolTaskScheduler-1 即可,因为默认线程大小是1,所以所有任务的工作线程名称都是他)
12点26 SyncMaterials 任务执行完毕,开始执行 SyncDataService
12点35 SyncDataService 任务执行完毕,开始执行 ScheduleService
再看看之前几天的日志,佐证一下猜想,可以看到确实是差不多每半小时执行一次。

解决方案
1、手工设置ThreadPoolTaskScheduler线程池大小,使其与定时任务数保持一致,每个任务用单独的工作线程,互不干扰(定时任务太多时其实存在资源浪费,每个任务都会有一个工作线程单独执行,间隔时间长且执行时间短的任务会始终占用着这个线程资源)
2、不要用spring自带的ThreadPoolTaskScheduler了,自己使用ScheduledExecutorService实现任务调度
3、找其他更合适的框架实现定时任务调度
结语
劲酒虽好,可不要贪杯哦!!!
脑子里为什么突然就有画面了???我还年轻,我一定不知道这些老年人才知道的广告词!!!
说正经的:不知道自己不知道->知道自己不知道->不知道自己知道->知道自己知道,咱们要努力做到最后面的那种境界。
套用到代码的世界就是,小白时期好多东西都不知道,定时任务都不知道是什么,只知道每天做自己已知的事儿,不就是增删改查嘛,有什么难的,大家都这样干,我也这样干;
后来听人家说了,有个定时任务的概念,spring可以实现这个功能,可以怎么用,自己遇到类似需求的时候,直接就去网上找关键字spring 定时任务,管他天高路远,管他山高水长,用就完了,干就是了;
再后来掉的坑多了,就知道看源码了,知道去看spring定时任务的原理了,后续工作中也知道再用spring定时任务的时候需要避免采什么坑,如何避免了,一阵沾沾自喜;
但后来被别人问的多了,或者自己开窍了,就知道除了spring自带了定时任务执行器,还有很多其他的方式可以实现相同的功能,他们各自的适用场景及优劣势是什么,自己当前的业务场景更适合用哪一种?开始做技术选型及预研了,这才是我们要追求的目标。
spring定时任务ThreadPoolTaskScheduler使用注意事项之线程池大小的更多相关文章
- 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事
线程池应该设置多少线程合适,怎么样估算出来.最近接触到一些相关资料,现作如下总结. 最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊. 首先,需要考虑到线程池所 ...
- 如何决定Web应用的线程池大小
线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...
- 如何计算tomcat线程池大小?
背景 在我们的日常开发中都涉及到使用tomcat做为服务器,但是我们该设置多大的线程池呢?以及根据什么原则来设计这个线程池呢? 接下来,我将介绍本人是怎么设计以及计算的. 目标 确定tomcat服务器 ...
- 发一个可伸缩线程池大小的python线程池。已通过测试。
发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...
- 如何决定 Web 应用的线程池大小
在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务.通常是通过 ...
- Java-如何合理的设置线程池大小
想要合理配置线程池线程数的大小,需要分析任务的类型,任务类型不同,线程池大小配置也不同. 配置线程池的大小可根据以下几个维度进行分析来配置合理的线程数: 任务性质可分为:CPU密集型任务,IO密集型任 ...
- Spring配置Quartz任务调度、及 ThreadPool 线程池
ONE.除了引入 Spring 相关的 jar 包,还要引入 Quartz 的 jar 包 <dependency> <groupId>org.springframework& ...
- ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别
工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍ThreadP ...
- 根据CPU核数合理设置线程池大小
一般来说池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可. 我们所需要关心的主要是核心池线程的数量该如何设置. 自定义线程池代码 package com. ...
随机推荐
- C# 显示、隐藏窗口对应的任务栏
WPF中全屏窗口,会自动隐藏任务栏. 那非全屏窗口如何隐藏任务栏?甚至有没有一种场景,隐藏任务后自定义一套系统任务栏来显示? 以下会分阶段讲述一些概念 1. 主屏任务栏 任务栏,其实也是一个窗口,主屏 ...
- The art of multipropcessor programming 读书笔记-硬件基础2
本系列是 The art of multipropcessor programming 的读书笔记,在原版图书的基础上,结合 OpenJDK 11 以上的版本的代码进行理解和实现.并根据个人的查资料以 ...
- JS中变量的命名规范
命名规范 包含数字.字母.下划线和$,但 不能以数字开头 变量名严格区分大小写 变量名不能是关键字和保留字 变量名要见名知意 如果变量名有多个单词组成,推荐使用 小驼峰命名法 命名时,尽量使用英语,如 ...
- VS运行时 /MD、/MDd 和 /MT、/MTd之间的区别
程序运行时出现问题,选择的是Release,win64位的模式,并且已经看到了宏定义NDEBUG,但是程序依然进入上面的部分 解决方案是将属性->C/C++->代码生成器->运行库里 ...
- Serverless 的初心、现状和未来
作者 | 不瞋 导读:Serverless 是如何产生的?当前有哪些落地场景?Serverless 的未来又将如何?本文分享了阿里云高级技术专家不瞋对于 Serverless 的看法,回顾其发展历程, ...
- 题解 「BZOJ4919 Lydsy1706月赛」大根堆
题目传送门 题目大意 给出一个 \(n\) 个点的树,每个点有权值,从中选出一些点,使得满足大根堆的性质.(即一个点的祖先节点如果选了那么该点的祖先节点的权值一定需要大于该点权值) 问能选出来的大根堆 ...
- 题解 [HNOI2007]分裂游戏
题目传送门 题目大意 有趣的取石子游戏即将开始. 有 \(n\) 堆石头,编号为 \(0,1,2,...,n-1\).两个人轮流挑石头. 在每个回合中,每个人选择三堆编号为 \(i,j,k\) 的石头 ...
- 数字IC设计工程师的知识结构
刚毕业的时候,我年少轻狂,以为自己已经可以独当一面,庙堂之上所学已经足以应付业界需要.然而在后来的工作过程中,我认识了很多牛人,也从他们身上学到了很多,从中总结了一个IC设计工程师需要具备的知识架构, ...
- LeetCode:链表专题
链表专题 参考了力扣加加对与链表专题的讲解,刷了些 leetcode 题,在此做一些记录,不然没几天就没印象了 出处:力扣加加-链表专题 总结 leetcode 中对于链表的定义 // 定义方式1: ...
- JAVA的array中indexOf
记得龙哥有个重构的文章里说直接判断啥的. 今天看JDK ArrayList,看到了他的 indexOf,他先判断,后进入循环,看似写了两遍for 循环,但是简单明了暴力.i like it . pub ...