Linux 服务器CPU超高如何快速定位
Linux 服务器CPU超高如何快速定位
前言
在生产环境中有时会遇见服务器CPU超高的问题,特别是重大版本发布后如果有内存泄露很容出现CPU超高,严重可能会达到100%。现在我们使用的服务器都是多核CPU,当出现CPU告警我们需要及时发现问题代码并处置,不然严重情况下会导致服务器宕机。
如何快速定位
1、找到最耗CPU进程
2、找到最耗CPU线程
3、找到线程堆栈信息
4、找到问题代码并处置
定位工具top
top [-] [d] [p] [q] [c] [C] [S] [n]
参数:
d:指定每两次屏幕信息刷新之间的时间间隔,当然用户可以使用s交互命令来改变之
p:通过指定监控进程ID来仅仅监控某个进程的状态
q:该选项将使top没有任何延ch迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行
S:指定累计模式
s:使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险
i:使top不显示任何闲置或者僵死进程
c:显示整个命令行而不只是显示命令名
H:显示线程
本次定位我们需要用到:
c:显示整个命令行而不只是显示命令名
H:显示线程
小试牛刀
我们以测试环境为例,找出最耗CPU线程堆栈并定位代码
1、找到最耗CPU的进程
-
执行top -c ,显示进程运行信息列表,c参数作用是显示整个命令行
-
键入P (大写p),进程按照CPU使用率排序
图示:
如上图,最耗CPU的进程PID为1,查看命令行可以看到是loanOrder服务。
2、找到最耗CPU的线程
-
top -Hp 1 显示一个进程的线程运行信息列表,参数H就是显示线程,参数p则是仅仅监控pid
-
键入P (大写p),线程按照CPU使用率排序
图示:
如上图,进程1内,最耗CPU的线程PID为750。
3、找到线程堆栈信息
3.1 将线程PID转化为16进制,需要使用命令 printf "%x\n" 线程PID
[root@devops-01 /]# printf "%x\n" 750
2ee
如上750的16进制2ee,之所以要转化为16进制,是因为堆栈里线程id是用16进制表示的。
3.2 根据查到进程下线程750过滤得到堆栈信息,此时需要使用命令
jstack 进程PID | grep '线程PID' -C5 --color
jstack 1 | grep '2ee' -C5 --color
图示:
如上图,找到了耗CPU高的线程对应的线程名称“http-nio-7014-exec-9"”,以及看到了该线程正在执行代码的堆栈。
4、根据堆栈信息找到问题代码并合理处置
目前是在锁等待的状态。在实际的内存泄露场景中,一般此时就会展示发生内存泄露的代码。
总结:用命令找到影响CPU的堆栈代码是最方便的,当然也可以采用arthas诊断工具,只是需要安装工具包然后也是看控制台找到线程ID,然后根据线程堆栈定位代码。