Java守护线程踩坑记

笔者最近在排查一次线上故障时, 发现一个很奇怪的现象: 线上服务启动时,没有任何流量和访问,服务cpu使用率莫名妙达到25%。 一开始不为其然,认为是项目中使用了公司自研的中间件, 导致了cpu使用率偏高。后面通过排查发现,其实是java守护线程使用方式出了问题,谨以此文章记录下排查过程,以及反思结果。

1. 查看服务器cpu 使用最高进程id

在服务器中使用top 命令,查看当前cpu使用率排名靠前的进程id

sh> top 
Java守护线程踩坑记_第1张图片
image.png

从上图中可以看到 java 进程占据了cpu将近25%的使用率

2. 找出对应的哪个子线程占据了主要的使用时间 top -H -p pid #查看异常的线程

从第一步可以看出,当前cpu使用率最高的进程 id 是1

> top -H -p 1
Java守护线程踩坑记_第2张图片
image.png

从上图找出来了对应的子线程的 id 为66

3. 将进程id 转为 16进制 printf "%x\n" tid

#  printf "%x\n" 66
42

4. 通过jstack 命令查找出异常线程

> jstack 1|grep 0x42 -A 30
Java守护线程踩坑记_第3张图片
image.png

5 修改代码

从4步骤找出来异常代码是TopicSender.java 36行。
至此,异常代码定位出来, 接下来就是如何修改代码。
源代码

Java守护线程踩坑记_第4张图片
image.png

源代码很简单,就是一个守护线程,不停循环的运行, 没有什么异常逻辑, 百思其解了好久,想要不让线程每运行一次就调用一次 Thread.sleep()。我这边设定了先试着 sleep 500ms 看看效果
Java守护线程踩坑记_第5张图片
image.png

然后就是部署,查验效果后,cpu使用率下降至2%
Java守护线程踩坑记_第6张图片
image.png

最后的结语

一次简单的问题排查,让我对java的线程使用更加熟练, 同时也学会了如何去排查线上服务cpu使用率偏高的手段。 同时也再次给我一次警醒。故障往往是因为不在意的小问题,及时发现问题, 及时解决问题。

参考:

1> https://www.cnblogs.com/zyhxhx/p/4564953.html

你可能感兴趣的:(Java守护线程踩坑记)