一、故障起因

起因是用户反馈系统很卡,我登录普罗米修斯一看,发现docker部署得集群下的一个java应用服务器cpu爆了,直接冲到了1000%以上了,接着就是各种接口超时报警等,赶紧打开对应的服务器查看进程情况,这会使用jstack和top命令定位哪个线程占用的cpu比较大,定位代码问题。

【瞎折腾日常】服务器的cpu飙高到1000%了怎么破_堆栈


二、常见的cpu100%以上异常的情况

程序中存在内存泄漏或者内存溢出,导致 JVM 不断进行垃圾回收;
代码中调用的某些资源造成的死锁或者是代码的死循环导致的cpu超频计算,或者长时间占用cpu的操作,像一些递归的使用、循环操作等等,或者一些特别复杂的正则匹配引起;
程序中存在大量的 IO 操作;
程序中存在大量的数据库操作,导致数据库连接池的耗尽和数据库负载过高。

三、排查方法

排查cpu过高的java导出日志,交给开发排查问题
1.top查看cpu使用率比较高的线程

top打印

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 900635 root      20   0   36.1g  19.4g  70976 S 153.0  30.7   5619:07 java

2.找出java里面cpu占用最高的pid
top -Hp 900635

901182 root      20   0   36.1g  19.4g  70976 R  26.1  30.7   5:02.85 httpWorkerThrea

3.然后将占用最高的pid转换为16进制
printf '%x\n' 901182 

[root@host-192-168-2-71 ~]# printf '%x\n' 901182
dc03e


4.接着直接使用jstack导出java进程900635的堆栈信息

 jstack -l 900635 > ./jstack_result.log


5.接着直接导出的堆栈文件里面中找到相应的16进制转换后的线程堆栈信息 

cat jstack_result.log |grep  -A 200 'nid=0xdc03e'

【瞎折腾日常】服务器的cpu飙高到1000%了怎么破_java_02

【瞎折腾日常】服务器的cpu飙高到1000%了怎么破_堆栈_03

【瞎折腾日常】服务器的cpu飙高到1000%了怎么破_堆栈_04


四、内存占用率高如何分析和优化

使用top -p pid针对所要查的 pid 查看该进程的 CPU 和内存以及负载情况。
jmap -histo:live [pid],然后分析具体的对象数目和占用内存大小,从而定位代码。
jmap -dump:live,format=b,file=xxx.xxx [pid],然后利用 MAT 工具分析是否存在内存泄漏等等。