一次上线新接口后cpu飚高40%内存升高的问题排查

现象:


一次上线新接口后cpu飚高40%内存升高的问题排查_第1张图片
image.png

排查步骤:
1.看内存情况

free -m -h
一次上线新接口后cpu飚高40%内存升高的问题排查_第2张图片
image.png

2.查看本台机器上的所有进程,找到本项目所属PID

ps axu | grep keep(公司关键字)
image.png

3.从本机器上找jmap工具


一次上线新接口后cpu飚高40%内存升高的问题排查_第3张图片
image.png

终于找到啦

4.用jmap工具排查

./jmap -histo:live 11505(PID)
./jmap -histo:live 11505 | head -30 
一次上线新接口后cpu飚高40%内存升高的问题排查_第4张图片
image.png

一次上线新接口后cpu飚高40%内存升高的问题排查_第5张图片
前三十情况

我们发现,最大的对象占用的内存也就20多兆,一般来说不可能是内存泄露(基本都是百万量级),排除此怀疑。后来发现这台机器上有很多项目共享,所以一启动内存就占60%左右。

5.那cpu为什么一下涨40%呢?我们继续排查

//查看本机内存情况
ps -mp 11505 -o THREAD,tid,time | sort -rn | more
一次上线新接口后cpu飚高40%内存升高的问题排查_第6张图片
image.png

6.用jstack工具分析

//转十六进制
printf "%x" 11588
//查看这个进程中线程情况
./jstack 11505 | grep 2d44 -A 30
一次上线新接口后cpu飚高40%内存升高的问题排查_第7张图片
image.png

继续查看top的进程


一次上线新接口后cpu飚高40%内存升高的问题排查_第8张图片
image.png

我们查看了cpu最高的一个进程下的几个子线程,发现并没有占用cpu过多的情况,那可能是大家都占不多,但线程同时开启的太多,并没有及时关闭,导致飚高。
我们继续找了几个线程查看具体情况,发现大部分情况都类似,处于"grpc-default-executor-26" #791 daemon prio=5 os_prio=0 tid=0x00007f8a3404b000 nid=0x4d87 waiting on condition [0x00007f8a0c2ac000]情况:


一次上线新接口后cpu飚高40%内存升高的问题排查_第9张图片
image.png

我们继续用jstack查看这个进程下的具体情况,发现罪魁祸首就是http-nio-8028-exec-*,可惜这个名字并不能看出什么问题(说明合理命名线程多么重要!):
./jstack 11505
一次上线新接口后cpu飚高40%内存升高的问题排查_第10张图片
image.png

将此文件拷贝一份

./jstack 11505 > ~/j.txt
vim j.txt
grep "http-nio-8028-exec" j.txt 
//统计个数
grep "http-nio-8028-exec" j.txt | wc -l
一次上线新接口后cpu飚高40%内存升高的问题排查_第11张图片
居然有196个

我们仔细分析了下这个线程,发现是tomcat在qps较高时会同时启动线程任务池,默认200个,所以基本可以排除代码有问题的可能了。


一次上线新接口后cpu飚高40%内存升高的问题排查_第12张图片
image.png

继续压测了一晚上之后,发现各项指标都比较平稳。至此,真相大白,告一段落。

你可能感兴趣的:(一次上线新接口后cpu飚高40%内存升高的问题排查)