线上 CPU 飙高如何排查?

Sherwin.Wei Lv7

线上 CPU 飙高如何排查?

回答重点

线上 CPU 飙高是一个比较常见的问题,并且它的排查手段比较流程化,非常适合套在各个项目中,大家按照我下面的思路简单加点细节就可以使用在自己的项目上了。

1)首先确认哪个进程占用 CPU 过高,登录服务器利用 top 命令查看。

top 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于 Windows 的任务管理器

2)确认 CPU 利用率很高的进程的 PID,假设为 1234 确实是 Java 进程,则通过 top -Hp 1234 查看具体的线程。

3)假设得到的线程 ID 是 5678,再将线程转为十六进制。

printf "%x\n" 5678

4)得到十六进制的 tid 为 162e,此时在利用 jstack 1234 | grep 162e -A 100 查看具体的栈信息。

jstack 命令用于生成虚拟机当前时刻的线程快照。 线程快照是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因, 如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。

grep (global regular expression) 命令用于查找文件里符合条件的字符串或正则表达式, -A 100 表示查找到匹配行后,额外再输出 100 行,便于我们查看堆栈信息。

5)根据堆栈信息就可以定位到具体是哪行代码导致了 CPU 飙高,对应分析修复即可!

常见可导致 CPU 飙高的代码问题

这里列举一些常见的代码问题,便于大家套用,例如:频繁实例化重对象(实例化过程很重,例如发号器实例、缓存实例等)、一些算法复杂度很高的操作(例如套用了 3 层以上的 for 循环)、死循环或错误的递归调用、频繁的 new 对象导致频繁垃圾回收等等。

CPU 飙得很厉害了,导致 ssh 都连不上?

一般情况下,CPU 即使 100% ,ssh 还是能连上的,只是会有点卡。

其次一般云服务提供产商它不依赖 SSH,类似一种提供了图形化的控制方法,让你可以像直接使用物理机一样访问和控制远程服务器。

再则一般现在服务都是弹性扩缩容的,也就是 CPU 在飙到一定阈值的时候,已经扩容了,例如 CPU 在一定的时间窗口内都持续在 80% 则增加机器扩容。如果代码有问题,则在新增的机器上监控一段时间也能定位到问题。

Comments