背景

最近小伙伴解决了一个工单,描述为“手工推送案件无法推,提示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使用注意事项之线程池大小的更多相关文章

  1. 线程池大小设置,CPU的核心数、线程数的关系和区别,同步与堵塞完全是两码事

    线程池应该设置多少线程合适,怎么样估算出来.最近接触到一些相关资料,现作如下总结. 最开始接触线程池的时候,没有想到就仅仅是设置一个线程池的大小居然还有这么多的学问,汗颜啊. 首先,需要考虑到线程池所 ...

  2. 如何决定Web应用的线程池大小

    线程池(Thread Pool)在Web应用中线程池的大小决定了在任何一个时间点应用可以处理请求的并发数.如果一个系统收到的请求数超过了线程池的大小,那么超出的请求要么进入等待队列要么被拒绝.请注意, ...

  3. 如何计算tomcat线程池大小?

    背景 在我们的日常开发中都涉及到使用tomcat做为服务器,但是我们该设置多大的线程池呢?以及根据什么原则来设计这个线程池呢? 接下来,我将介绍本人是怎么设计以及计算的. 目标 确定tomcat服务器 ...

  4. 发一个可伸缩线程池大小的python线程池。已通过测试。

    发一个可伸缩线程池大小的线程池. 当任务不多时候,不开那么多线程,当任务多的时候开更多线程.当长时间没任务时候,将线程数量减小到一定数量. java的Threadpoolexcutor可以这样,py的 ...

  5. 如何决定 Web 应用的线程池大小

    在部署 web 应用到生产环境,或者在对 web 应用进行性能测试的时候,经常会有人问:如何决定 web 应用线程池大小?决定一个 IO 阻塞型 web 应用的线程池大小是一项很艰巨的任务.通常是通过 ...

  6. Java-如何合理的设置线程池大小

    想要合理配置线程池线程数的大小,需要分析任务的类型,任务类型不同,线程池大小配置也不同. 配置线程池的大小可根据以下几个维度进行分析来配置合理的线程数: 任务性质可分为:CPU密集型任务,IO密集型任 ...

  7. Spring配置Quartz任务调度、及 ThreadPool 线程池

    ONE.除了引入 Spring 相关的 jar 包,还要引入 Quartz 的 jar 包 <dependency> <groupId>org.springframework& ...

  8. ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别

    工作中多处接触到了ThreadPoolExecutor.趁着现在还算空,学习总结一下. 前记: jdk官方文档(javadoc)是学习的最好,最权威的参考. 文章分上中下.上篇中主要介绍ThreadP ...

  9. 根据CPU核数合理设置线程池大小

    一般来说池中总线程数是核心池线程数量两倍,只要确保当核心池有线程停止时,核心池外能有线程进入核心池即可. 我们所需要关心的主要是核心池线程的数量该如何设置. 自定义线程池代码 package com. ...

随机推荐

  1. 51nod1821-最优集合【贪心】

    正题 题目链接:http://www.51nod.com/Challenge/Problem.html#problemId=1821 题目大意 \(n\)个可重集合,\(T\)次询问,询问将集合\(S ...

  2. Loj#6247-九个太阳【单位根反演】

    正题 题目链接:https://loj.ac/p/6247 题目大意 给出\(n,k\)求 \[\sum_{0\leq i\leq n,i|k}\binom{n}{i} \] 对\(998244353 ...

  3. CF803G-Periodic RMQ Problem【离散化,线段树,ST表】

    正题 题目链接:https://www.luogu.com.cn/problem/CF803G 题目大意 一个长度为\(n\)的序列\(a\)复制\(k\)份连接,要求支持 区间赋值 区间查询最小值 ...

  4. selenium--常用判断

    获取页面 title 的方法可以直接用 driver.title 获取到,然后也可以把获取到的结果用做断言.1.首先导入 expected_conditions 模块:from selenium.we ...

  5. linux 测试2

    .阅读目录●第一种:cat /dev/null > filename●第二种:: > filename●第三种:> filename●第四种:echo "" &g ...

  6. docker-compose 搭建kafka集群

    docker-compose搭建kafka集群 下载镜像 1.wurstmeister/zookeeper 2.wurstmeister/kafka 3.sheepkiller/kafka-manag ...

  7. C++学习 1 数组

    一维数组: 定义:1.数据类型 数组名 [ 数组长度 ]: int arr [5];//赋值 arr[0]=10; arr[1]=20; arr[2]=30; arr[3]=40; arr[4]=50 ...

  8. asp.net core使用identity+jwt保护你的webapi(二)——获取jwt token

    前言 上一篇已经介绍了identity在web api中的基本配置,本篇来完成用户的注册,登录,获取jwt token. 开始 开始之前先配置一下jwt相关服务. 配置JWT 首先NuGet安装包: ...

  9. 网络协议之:加密传输中的NPN和ALPN

    目录 简介 SSL/TLS协议 NPN和ALPN 交互的例子 总结 简介 自从HTTP从1.1升级到了2,一切都变得不同了.虽然HTTP2没有强制说必须使用加密协议进行传输,但是业界的标准包括各大流行 ...

  10. 【二食堂】Alpha - Scrum Meeting 8

    Scrum Meeting 8 例会时间:4.18 11:40 - 12:10 进度情况 组员 昨日进度 今日任务 李健 1. 实体的添加和关系的添加实现的有bug,柴博和刘阳进行了帮助issue 1 ...