背景

最近小伙伴解决了一个工单,描述为“手工推送案件无法推,提示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. k8s负载资源StatefulSet工作解析

    在k8s中工作负载资源StatefulSet用于管理有状态应用. 什么是无状态? 组成一个应用的pod是对等的,它们之前没有关联和依赖关系,不依赖外部存储. 即我们上篇小作文中deployment创建 ...

  2. 基于C++的ButeBuf封装

    目录 1.说明 2.代码 1.说明 netty 的 ByteBuf 中的 readerIndex 和 writerIndex 的设置十分巧妙,它内部对读取和写入位置进行控制,避免自己处理index的时 ...

  3. 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?

    通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  4. bzoj1972 SDOI2010-----猪国杀(模拟)

    题目自己去找吧 记得数据范围是<=10 注意事项: 1.牌库空的时候,要不断的抽第一张牌 2.反贼的决斗永远是向主公发的 3.每次判定无懈的时候,都是从使用锦囊的那个牌开始,记得敌意和殷勤的判断 ...

  5. Fastjson中getJSONObject()与getJSONArray()的使用

    测试JSON串: { "package": { "List1": { "errorCode": "0", "e ...

  6. 解决el-checkbox-group 的v-model无法绑定对象数组

    elementUI官方文档中el-checkbox-group组件绑定的都为一维数组,真实业务中数据绑定往往是多个键值对的对象数组,本文主要解决这个问题. 如下代码: <el-checkbox- ...

  7. 【UE4 设计模式】策略模式 Strategy Pattern

    概述 描述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法的变化不会影响到使用算法的客户. 套路 Context(环境类) 负责使用算法策略,其中维持了一 ...

  8. airtest常用指令

    airtest 操作adb命令   常用adb 1)对特定设备执行adb指令 dev = connect_device("Android:///device1") dev.shel ...

  9. python画图的工具及网站

    ①Gallery - Matplotlib 3.4.3 documentation 学会模仿并超越 ②Examples - Apache ECharts js网页端动态展示 ③WEB色見本 原色大辞典 ...

  10. 洛谷 P3195 [HNOI2008] 玩具装箱

    链接: P3195 题意: 给出 \(n\) 个物品及其权值 \(c\),连续的物品可以放进一个容器,如果将 \(i\sim j\) 的物品放进一个容器,产生的费用是 \(\left(j-i+\sum ...