前言
当收到线上服务器 CPU 负载过高告警时,要怎么做?重启服务?忽略告警?别人不知道怎么做,但是作为一个程序猿,是一定要定位到具体问题所在并FIX它。
下面记录一下服务器 CPU 负载过高排查过程,把排查流程理清楚,以后遇到问题将会迅速定位到问题所在,快速解决。
什么样的场景会导致线上CPU负载过高?
代码层面常见的场景有:
程序陷入死循环,不停地消耗CPU
线程死锁,线程相互等待,导致假死状态,不停地消耗CPU
模拟程序死循环场景
这里使用 JAVA 简单模拟程序死循环带来的系统高负载情况,代码如下:
1 | package li.xiaolong.test.exception; |
定位过程
top查找占用CPU高的进程
1 | top |
如下图:可看出PID为 4369 的java进程占用cpu最高,达到了99.7%。
查看进程中最耗cpu的子线程
1 | top -Hp 4369 |
如下图:可看出PID为 4372 的线程占用cpu最高,达到了99.7%
线程id转换为16进制
1 | printf "%x \n" 4372 |
得到16进制数 1114 。
定位问题代码
使用jstack查看进程堆栈信息,定位占cpu最高的线程对应问题代码。1
jstack 4369 | grep 1114 -A 30
如下图:可看出问题代码正是模拟程序死循环的代码。
至此,问题定位结束。