多线程引发的血案
问题出现的现象
我们的微服务网关运行出现了两次的自动下线,然后看日志并没有报错信息。所以我们初步怀疑是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