2026-05-13 12:39:34
一次线上服务CPU飙升至100%的应急处理过程记录如下:
告警阶段使用docker stats命令查看本节点容器资源使用情况。
对占用CPU高的容器,使用docker exec -it <容器ID> bash命令进入容器内部。
在容器内部执行top命令,定位到占用CPU高的进程ID。
使用top -Hp <进程ID>命令,进一步定位到占用CPU高的线程ID。
使用jstack <进程ID> > jstack.txt命令,将进程的线程栈打印输出到文件。
退出容器,使用docker cp <容器ID>:/usr/local/tomcat/jstack.txt ./命令,将jstack文件复制到宿主机,以便查看。
获取到jstack信息后,重启服务以恢复其可用性。
使用printf '%xn' <线程ID>命令,将线程ID转换为十六进制形式。
在jstack.txt文件中定位到nid=0x<十六进制线程ID>的位置,该位置即为占用CPU高线程的执行栈信息。
与同事确认,发现高CPU占用与使用一个框架的excel导出功能有关。该功能未设置分页和限制,一次导出50万条数据,且每条数据都需要进行转换计算。操作者因导出无响应而连续点击,几分钟内发起了10多次导出请求,导致CPU被打满,服务崩溃。
依前面步骤定位到占用CPU高的线程,发现与GC任务线程相关。
使用jstat -gcutil <进程ID> 2000 10命令查看GC情况。
使用jmap -heap <进程ID>查看堆内存各区的占用情况。
使用jmap -dump:format=b,file=./jmap.dump <进程ID>命令将内存使用情况dump出来。
退出容器,使用docker cp <容器ID>:/usr/local/tomcat/jmap.dump ./命令将dump文件复制到宿主机目录,下载到本地。
使用MemoryAnalyzer工具打开dump文件进行分析。

