CPU负载过高异常定位排查

前言

当收到线上服务器 CPU 负载过高告警时,要怎么做?重启服务?忽略告警?别人不知道怎么做,但是作为一个程序猿,是一定要定位到具体问题所在并FIX它。

下面记录一下服务器 CPU 负载过高排查过程,把排查流程理清楚,以后遇到问题将会迅速定位到问题所在,快速解决。

什么样的场景会导致线上CPU负载过高?

代码层面常见的场景有:

程序陷入死循环,不停地消耗CPU
线程死锁,线程相互等待,导致假死状态,不停地消耗CPU

模拟程序死循环场景

这里使用 JAVA 简单模拟程序死循环带来的系统高负载情况,代码如下:

1
2
3
4
5
6
7
8
9
10
11
package li.xiaolong.test.exception;

public class CPUDemo {

public static void main(String[] args) {
int i= 0;
while (true) {
i++;
}
}
}

定位过程

top查找占用CPU高的进程
1
top

如下图:可看出PID为 4369 的java进程占用cpu最高,达到了99.7%。
image

查看进程中最耗cpu的子线程
1
top -Hp 4369

如下图:可看出PID为 4372 的线程占用cpu最高,达到了99.7%
image

线程id转换为16进制
1
printf "%x \n" 4372

得到16进制数 1114

定位问题代码

使用jstack查看进程堆栈信息,定位占cpu最高的线程对应问题代码。

1
jstack 4369 | grep 1114 -A 30

image

如下图:可看出问题代码正是模拟程序死循环的代码。

至此,问题定位结束。

----------本文结束感谢您的阅读----------
xiaolong wechat
一只程序猿对世界的不完全理解