回答重点
线上CPU 飙高是一个比较常贝的问题,并且它的排查手段比较流程化,非常适合套在各个项目中,大家按照我下面的思路简单加点细节就可以使用在自己的项目上了。
- 首先确认哪个进程占用 CPU 过高,登录服务器利用 top 命令查看。
top 命令是 Linux 下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于 Windows 的任务管理器,这里需要着重了解怎么看,load average 的作用等,详情可以看top命令
- 确认 CPU 利用率很高的进程的 PID,假设为 1234 确实是Java 进程,则通过 top -Hp 1234 查看具体的线程。
- 假设得到的线程ID 是 5678,再将线程转为十六进制。 printf "%x\n” 5678
- 得到十六进制的 tid为162e,此时在利用 jstack 1234 | grep 162e -A 100 查看具体的栈信息。jstack命今用于生成虚拟机当前时刻的线程快照。线程快照是当前虚拟机内每一条线程上在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、 请求外部资源导致的长时间等待等问题
- 根据堆栈信息就可以定位到具体是哪行代码导致了CPU 高,对应分析修复即可!
常见可导致 CPU 飙高的代码问题
这里列举一些常见的代码问题,便于大家套用,例如:频繁实例化重对象(实例化过程很重,例如发号器实例、缓存实例)、一些算法复杂度很高的操作 (例如套用了3层以上的for循不)、死循环或者错误的递归调用、频繁的new对象导致频繁垃圾回收等等。
CPU 飙得很厉害了,导致 ssh 都连不上?
一般情况下,CPU 即使 100%,ssh还是能连上的,只是会有点卡。
其次一般云服务提供产商它不依赖SSH,类似一种提供了图形化的控制方法,让你可以像直接使用物理机一样访问和控制远程服务器。再则一般现在服务都是弹性扩缩容的,也就是 CPU在达到一定阈值的时候,已经扩容了,例如 CPU 在一定的时间窗口内都持续在 80%则增加机器扩容。如果代码有问题,则在新增的机器上监控一段时间也能定位到问题