排查生产环境CPU过高的问题
检查系统内存和CPU的使用情况
- free工具用来查看系统可用内存:
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/free.html
[root@iz6ammapnl2v4ez ~]# free
total used free shared buff/cache available
Mem: 1883724 1603884 89592 436 190248 121560
Swap: 0 0 0
Mem指的是内存,Swap指的是交换分区 每一列分别是交换的总量(total),使用量(used)和有多少空闲的交换区(free)。
- top linux下的任务管理器
https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/top.html
[root@iz6ammapnl2v4ez ~]# top
top - 13:43:24 up 24 days, 23:08, 1 user, load average: 0.00, 0.01, 0.05
Tasks: 69 total, 1 running, 68 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1883724 total, 84608 free, 1603836 used, 195280 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 121604 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
21605 root 0 -20 128552 8560 5052 S 200 0.5 76:17.81 resin
1 root 20 0 43180 2380 1252 S 0.0 0.1 0:10.70 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
进程信息
PID:进程的ID
USER:进程所有者
PR:进程的优先级别,越小越优先被执行
NInice:值
VIRT:进程占用的虚拟内存
RES:进程占用的物理内存
SHR:进程使用的共享内存
S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
%CPU:进程占用CPU的使用率
%MEM:进程使用的物理内存和总内存的百分比
TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
COMMAND:进程启动命令名称
通过top命令我发现pid-21605 Resin应用CPU占用率一直很高而且停不下来。
通过top -Hp 21605 命令,可以查看到进程内的线程情况。
# top -Hp 21605
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
158166 admin 0 -20 5631m 4.0g 102m S 1.0 49.6 31:21.02 java
157051 admin 0 -20 5631m 4.0g 102m S 0.3 49.6 1:56.39 java
# jstack 21605 > /root/jstack.log
找到top -Hp 21605的PID对应的16进制
# printf %x 158166
269d6
# jstack 21605|grep -A 10 269d6
查找到具体线程状态,也可使用dump工具分析问题
注意:
top -Hp命令也可以换成使用 pidstat -p < PID > 1 3 -u -t
对于cpu飙升,一般来说有几个对象嫌疑重大:
嫌犯A:内存泄漏,导致大量full GC
嫌犯B:宿主机cpu超卖
嫌犯C:线程死锁,数据库死锁,代码存在死循环
由于遇到过类似的死锁的问题,我就先查找死锁问题。
- 死锁排查jstack 也可以使用idea的照相机看的当前的进程情况
### 查找进程号
jps -l
### 查看进程
直接查看
jstack -l 12316
导出文件
jstack 12316 > /root/jstack.log
线程的状态:
NEW,未启动的。不会出现在Dump中。
RUNNABLE,在虚拟机内执行的。
BLOCKED,受阻塞并等待监视器锁。
WATING,无限期等待另一个线程执行特定操作。
TIMED_WATING,有时限的等待另一个线程的特定操作。
TERMINATED,已退出的。
搜索一下有没有deadlock,这个就是死锁。发现没有死锁,那就继续查看线程状态。
发现有很多线程都在堵塞或者在执行,没错就是这个的问题,经过同事的帮助下确实发现了那块逻辑死循环跳不出来,不过我想写这个人现在早就高就了~~
- 由于当时没有留下记录下面图片从网上找了一个,大致差不多会告诉你哪一个方法出现的问题
补充其他神器:
- 1.Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。
https://github.com/alibaba/arthas/blob/master/README_CN.md
- 2.show-busy-java-threads脚本