字节面试:CPU100%,怎么快速定位?三步教你快速定位
作为开发人员或者运维人员,如何快速定位到引起CPU过载的服务、线程,以及代码,这对我们排查问题至关重要。
今天分享一下我平时处理类似问题的思路,希望对大家有所帮助!
步骤一:找到最耗CPU的进程
当我们发现服务器CPU出现异常高的负载时,第一步要做的就是找到最消耗CPU资源的进程。
我们可以使用top命令来查看当前所有进程的CPU使用情况。
工具: top方法:
执行top -c命令,显示进程的运行信息列表。
按下P键(大写的P),可以按照CPU使用率对进程进行排序。
通过这种方式,我们可以很容易找到CPU使用率最高的进程,假设最耗CPU的进程的PID为10765,接下来我们就要深入挖掘了。
图示: 如上图,最耗CPU的进程PID为10765。
步骤二:找到最耗CPU的线程
接下来,定位到特定进程后,我们要进一步找到在该进程内最耗CPU的线程。
这一步同样使用top命令,但这次我们需要使用-Hp选项来显示该进程内所有线程的使用情况。
工具: top方法:
执行top -Hp 10765命令,显示进程10765的线程运行信息。
同样按下P键(大写的P),按CPU使用率排序线程。
这样一来,我们可以找到在进程内最占用CPU资源的线程,假设它的PID为10804。
图示:
如上图,进程10765内最耗CPU的线程PID为10804。
步骤三:查看堆栈,定位线程在干嘛,找到对应代码
此时,我们已经找到了导致CPU高负载的线程,接下来就是查看这个线程到底在做什么。
首先,我们需要将线程的PID从十进制转换为16进制格式,因为堆栈信息中,线程的ID通常是以16进制表示的。
工具: printf方法:
执行命令printf "%x\n" 10804,将线程PID转化为16进制。你也可以使用计算器来做这一步。 图示:
如上图,线程PID 10804对应的16进制是0x2a34。
接下来,我们可以使用jstack命令查看该进程的堆栈信息,并通过线程的ID过滤出该线程的堆栈,进一步了解它在做什么。
工具: jstack方法:
执行jstack 10765 | grep '0x2a34' -C5 --color命令,打印进程10765的堆栈信息,并通过线程ID(0x2a34)来过滤并找到相关线程的堆栈。
图示:
如上图,找到了耗CPU高的线程对应的线程名称“AsyncLogger-1”,并且看到了该线程正在执行代码的堆栈。
根据堆栈信息,我们就可以追踪到代码中可能存在的性能瓶颈,进而定位到具体的代码位置。
总结
通过这三步,我们成功找到了导致CPU过载的线程以及相应的代码。希望这篇文章能够帮助经常进行线上排查的同学们,如果你有更好的实践或思路,也欢迎分享,大家一起进步!