线程数过高问题排查

1,232 阅读3分钟

前言

在我们日常工作中,排查项目的各种问题也是挺头大的,什么线程数、cpu、磁盘。。。系列的问题,线程问题问题也是经常遇到的一种。下面是我排查我们项目启动时候线程数过高的排查过程,看看大家有没有可以借鉴的。

还记得是一个阳光明媚的下午,我接手的A项目做了些简单的优化,组织代码Review没有问题就准备上线。顺提一下,我接手项目后加了一些监控比如:线程数、cup使用率、磁盘使用率等的监控。

【现象】

在那个阳光明媚的下,我熟练的进行上线操作:摘流量-服务编译打包-发布上线--接入流量。我刚上一台机器接入流量触发了线程数报警。。。此时心里一惊,赶紧停机想想有没有什么步骤漏下了。经过回想没漏下什么东西。然后就进行了一次重启,依旧触发报警。报警如下(内部自研监控工具): ​

警告:应用:A , JVM 监控:A-jvm, ip:127.0.0.1, JVM监控线程数2112 ,超过1次线程数>=1200个

微信图片_20220405192007.png

【猜测】

  • 有没有瞬间流量暴增导致的
  • 项目是不是里面有定时任务导致的
  • 是不是有什么特殊线程池处理导致的
  • 是不是新优化导致的
  • 到底是上线导致的还是接入流量导致的

【复现排查】

  1. 经过代码排查,确定不是新优化和定时任务导致的
  2. 项目中也主动使用线程池所以也不是
  3. 经过几次操作复现,发现只有上线接入流量时候才会这样而且持续一会就线程数就会降低下去。所以跟流量不会说特别大监控也可以看到,访问量很少。
  4. 所以排查那个上线的接口看到其功能使用到了自研缓存,猜测是这个问题导致的

【验证】

那咱们的JVM相关监控来了,我的问题主要是线程问题咱们的线程监控jstack线程监控工具。

稍微讲讲咱们jstack(监控线程)

主要作用:生成虚拟机当前时刻的线程快照文件。

命令格式:

jstack 【选项】 【进程ID】

命令:jstack -l 18230 >jstack.txt

拿到线程监控文件

微信图片_20220405192049.png 内容说明:

pool-2-thread-56:线程名称

tid:当前线程ID

线程状态:

waiting on condition      //等待条件
deadlock                  //死锁
waiting on monitor entry  //等待获取监视器
Blocked                   //阻塞
Runnable                //运行
Suspended             //暂停
TIMED_WAITING        //休眠(有超时限制)
WAITING             //休眠
Parked            //停止

工具讲了下,下面继续正题。看到我上面图片的线程 pool-2 开头的线程有2000+ 所以基本上确定是这个线程导致的,然后去找线程来源,经过代码的排查找到了线程高的根本原因(耗时大概1小时)我们自研缓存的源代码,底层使用的是默认线程池如下(自研工具有查询缓存预热会线程数变高):

微信图片_20220405192113.png

总结

  1. 遇到问题后不要慌冷静的分析下现象本质
  2. JVM相关的工具要熟悉
  3. 有些有问题遇到了一定要做计划排查,防止特殊情况下出大事故。