线上环境排查cpu飙高问题的思路
目录
TOP基础:
top执行后分析
top + 数字1:查看各逻辑CPU占用率
top + 小写字母u,然后输入用户名: 查看相应的用户进程。
top + 大写字母E: 切换内存信息区域显示单位 kb --> mb --> gb --> pb
CPU飙高问题排查步骤
第一步: 找到CPU占用飙高的线程ID
第二步:将TID(代码线程id)转为16进制
第三步:jstack查看进程信息
查看jvm信息其他命令
TOP基础:
选项信息:
$ top
#命令选项:
-d # 指定每两次屏幕信息刷新之间的时间间隔,如希望每秒刷新一次,则使用:top -d 1
-p # 通过指定PID来仅仅监控某个进程的状态
-S # 指定累计模式
-s # 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险
-i # 使top不显示任何闲置或者僵死的进程
-c # 显示整个命令行而不只是显示命令名
$ top #每隔3秒显式所有进程的资源占用情况
$ top -d 1 #每隔1秒显式所有进程的资源占用情况
$ top -c #每隔3秒显式进程的资源占用情况,并显示进程的命令行参数(默认只有进程名)
$ top -p 28820 -p 38830 #每隔3秒显示pid是28820和pid是38830的两个进程的资源占用情况
$ top -d 2 -c -p 69358 #每隔2秒显示pid是69358的进程的资源使用情况,并显式该进程启动的命令行参数
top执行后分析
top基础信息分析:
第一行:top - 17:32:43 up 98 days, 6:16, 2 users, load average: 0.29, 0.30, 0.30
top: 当前时间
up:机器运行了多久
users:当前登录用户数
load average: 系统负载,即任务队列的平均长度。三个数值分别为 1min、5min、15min前到现在的平均值。(一般来说,这个值不超过这台机器总核数,就基本没问题)
第二行:Tasks: 184 total, 1 running, 183 sleeping, 0 stopped, 0 zombie
Tasks:当前有多少进程
running :正在运行的进程数
sleeping:正在休眠的进程数
stopped:停止的进程数
zombie:僵尸进程数
第三行:%Cpu(s): 1.4 us, 1.2 sy, 0.0 ni, 97.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
us:用户空间占CPU的百分比
sy:内核空间占CPU的百分比
ni:用户进程空间改变过优先级
id:空闲CPU占用率
wa:等待输入输出的CPU时间百分比(和CPU的处理速度相比,磁盘IO操作是非常慢的,有很多这样的操作,比如,CPU在启动一个磁盘读写操作后,需要等待磁盘读写操作的结果。在磁盘读写操作完成前,CPU只能处于空闲状态。Linux系统在计算系统平均负载时会把CPU等待IO操作的时间也计算进去,所以在我们看到系统平均负载过高时,可以通过wa来判断系统的性能瓶颈是不是过多的IO操作造成的)
hi:硬中断占用百分比( 硬中断是硬盘、网卡等硬件设备发送给CPU的中断消息,当CPU收到中断消息后需要进行适当的处理(消耗CPU时间)
si:软中断占用百分比(软中断是由程序发出的中断,最终也会执行相应的处理程序,消耗CPU时间)
st:streal time
第四行:KiB Mem : 16265180 total, 279588 free, 12152976 used, 3832616 buff/cache
total:物理内存总量
free:空闲内存量
used:使用的内存量
buffer/cache:用作内核缓存的内存量
第五行:KiB Swap: 0 total, 0 free, 0 used. 2964648 avail Mem
total:交换区内存总量
free:空闲交换区总量
used:使用的交换区总量
buffer/cache:缓冲的交换区总量
进程数据分析:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4170 root 20 0 60048 9372 2460 S 5.3 0.1 1:04.63 nginx
2318 root 20 0 469548 89508 13428 T 3.3 0.6 69:07.39 titanagent
32223 root 20 0 8412724 950996 14596 S 3.0 5.8 145:43.92 java
667 dbus 20 0 60784 2676 1724 S 1.3 0.0 17:13.60 dbus-daemon
430 root 20 0 55820 19032 18636 S 1.0 0.1 10:37.53 systemd-journ
PID 进程id
USER 进程所有者的用户名
PR 优先级
NI nice值,负值标识高优先级,正值表示低优先级
VIRT 进程使用的虚拟内存总量、单位kb。VIRT=SWAP+RES
RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
SHR 共享内存大小,单位kb
S 进程状态。D=不可中断的睡眠状态、R=运行、S=睡眠、T=跟踪/停止、Z=僵尸进程
%CPU 上次更新到现在的CPU时间占用百分比
%MEM 进程使用的物理内存百分比
TIME+ 进程使用的CPU时间总计,单位1/100秒
COMMAND 命令名/命令行
top + 数字1:查看各逻辑CPU占用率
top + 小写字母u,然后输入用户名: 查看相应的用户进程。
top + 大写字母E: 切换内存信息区域显示单位 kb --> mb --> gb --> pb
CPU飙高问题排查步骤
第一步: 找到CPU占用飙高的线程ID
使用top查看目前服务所占cpu情况,找到CPU占用率过高的进程。
第二步:将TID(代码线程id)转为16进制
通过ps命令查看这个程序的线程信息。找出其中 %CPU 占用率很高的线程ID即TID。
展示 tid 代码线程ID,time代表这个线程已运行的时间,5187对应pid的值
$ ps -mp 5187 -o THREAD,tid,time
因为jvm运行信息都是16进制,所以需要将十进制转化为16进制。
$ printf “%x\n” 34523
第三步:jstack查看进程信息
查看jstack信息。 查看 进程pid为 5187,jvm线程pid为 86db 的堆栈信息。
$ jstack 5187 | grep 86db -A 30
根据代码信息快速定位问题。
查看jvm信息其他命令
#将各个区使用内存大小展示出来 jstat -gc 5187(pid) 2000(2s一次) 10(共计10次)
$ jstat -gc 5187 2000 10
#将各个区使用占比展示,能够更好分析 jstat -gcutil 5187(pid) 2000(2s一次) 10(共计10次)
$ jstat -gcutil 5187 2000 10
#将正在运行的线程的jvm堆栈日志保存到指定文件
$ jstack 5187 >>jstack.out