多线程引发的血案

问题出现的现象

我们的微服务网关运行出现了两次的自动下线,然后看日志并没有报错信息。所以我们初步怀疑是linux自己把这个进程给杀掉了。

排查思路

我们刚开始使用下面的命令,并没有发现有kill的日志

dmesg | egrep -i -B100 'killed process'
# 或者
egrep -i 'killed process' /var/log/messages
egrep -i -r 'killed process' /var/log
# 或者
journalctl -xb | egrep -i 'killed process'

所以我们又把服务重启后,使用

 ps p 516866 -L -o pcpu,pmem,pid,tid,time,tname,cmd

查到当前的任务启动了很多的线程。有差不多900个线程,所以初步确定是线程的问题导致的

 

 

然后使用

jstack -l 516866 > jstack.log 

我们打开jstack.log 这个日志文件

 

 

可以看到 有很多my-thread-1的线程在WAITING,这样的话我们就可以通过我们的代码寻找可能导致问题的原因

排查代码

因为线程有相应的名字,那么我们就可以通过这个名字定位到相应的代码

 

 

我们可以看到这段代码是消费kafka的数据,然后对数据进行一个处理。其中使用了线程池。

这段代码的问题出在了,没来一条数据就会创建一个线程池,所以导致创建了大量的线程,最后导致cpu暴增。

后来对代码的修改

 

我们把创建线程池的代码使用静态代码块的方式,然后来一条数据需要处理的时候,去线程池中获取就行。

效果

我们将代码重新部署后,再使用

ps p <pid> -L -o pcpu,pmem,pid,tid,time,tname,cmd

 

 

 

 

 

posted @ 2022-02-25 17:41  monkey66  阅读(49)  评论(0编辑  收藏  举报