注:本文只是为了辅助自己分析而记录
首先我们来分析一下top命令:
[root@localhost ~]# top
top - 19:24:45 up 1 day, 6:05, 3 users, load average: 0.00, 0.01, 0.05
Tasks: 419 total, 2 running, 417 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1868660 total, 176700 free, 190944 used, 1501016 buff/cache
KiB Swap: 2097148 total, 2097096 free, 52 used. 1419080 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 44516 7232 2596 S 0.0 0.4 0:17.07 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.12 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:09.46 ksoftirqd/0
7 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcuob/0
10 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcuob/1
11 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcuob/2
-
进程的状态:s列表示进程的状态
- R:是Running或者Runnable的缩写,标识进程在cpu的就绪队列汇总,正在运行或者正在等待运行
- D:是Disk Sleep的缩写,也就是不可中断状态睡眠(Uinterruptiable Sleep),表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断
- Z: 是Zoombie的缩写,表示僵尸进程,也就是进程实际上已经结束了,但是父进程没有回收它的资源
- S:是Interruptiable Sleep的缩写,也就是可中断状态睡眠,表示进程因为等待某个时间而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入R状态
- I:是idle的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。
- T或者t:就是stopped或Traced的缩写,表示进程处于暂停或者跟踪的状态
案例:
image.png问题分析:
- 1.第一行的平均负载,过去一分钟、5分钟和15分钟内的平均负载在依次减小,说明平均负载在升高;且1分钟的平均负载已经达到系统的cpu个数,说明系统很可能已经有性能瓶颈
- 2.第二行的Tasks,有1个正在运行的进程,但僵尸进程比较多,而且还在不停增加,说明有子进程在退出时没被清理
- 3.接下来看两个cpu的使用率情况,用户cpu和系统cpu使用率都不高,但iowait分别是60%和95%,不正常
- 4.有两个进程处于D状态,他们可能在等待I/O,但光凭这里不确定使它们导致的iowait升高
总结:
1、iowait太高,导致系统平均负载升高,达到了系统cpu的个数
2、僵尸进程在不断增多,说明有程序没能正确清理子进程的资源。
注:无法模拟上图的压力环境,所以只是介绍方法:
iowait分析
dstat
dstat可以同时查看cpu和I/O这两种资源的使用情况,便于对比分析;往往iowait升高,都伴随很高的读写请求
#每隔2秒加载1次,共加载10次
root@localhost ~]# dstat 2 10
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read writ| recv send| in out | int csw
1 1 98 0 0 0|4570B 335k| 0 0 | 0 1B| 42 26k
0 0 100 0 0 0| 0 0 | 60B 582B| 0 0 | 24 34
0 1 100 0 0 0| 0 0 | 60B 330B| 0 0 | 23 33
0 0 100 0 0 0| 0 0 | 60B 330B| 0 0 | 23 32
pidstat
pidstat加上-d参数可以查看进程的资源使用情况,输出I/O使用情况
[root@localhost ~]# pidstat -d -p 80309 1 3
Linux 3.10.0-327.el7.x86_64 (localhost.localdomain) 02/13/23 _x86_64_ (1 CPU)
22:31:29 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
22:31:30 0 80309 0.00 0.00 0.00 0 sysbench
22:31:31 0 80309 0.00 0.00 0.00 0 sysbench
22:31:32 0 80309 0.00 0.00 0.00 0 sysbench
Average: 0 80309 0.00 0.00 0.00 0 sysbench
- kB_rd表示每秒读的kb数,kB_wr表示每秒写的kb数,iodelay表示I/O的延迟。
strace
使用上面的工具发现造成iowait高的进程后,我们知道进程想要访问磁盘,就必须使用系统调用,所以接下来,重点就是找出app进程的系统调用了
使用strace跟踪进程系统调用
#-p 进程id
[root@localhost ~]# strace -p 847
perf
上面的strace找不到也可以使用perf
#实时查看
[root@localhost ~]#perf top -g -p pid
#生成报告查看
[root@localhost ~]#perf record -g
[root@localhost ~]#perf report
Samples: 5K of event 'cpu-clock', Event count (approx.): 1370500000
Children Self Command Shared Object Symbol
+ 34.80% 0.00% stress-ng-cpu [unknown] [.] 0x41d8facbc1336cc9
+ 34.80% 0.00% stress-ng-cpu [unknown] [.] 0x00007f595a7dce28
+ 9.56% 9.47% stress-ng-cpu stress-ng [.] stress_cpu_crc16
+ 7.04% 7.02% stress-ng-cpu stress-ng [.] stress_cpu_correlate
+ 6.71% 6.60% stress-ng-cpu stress-ng [.] stress_cpu_dither
+ 5.31% 5.29% stress-ng-cpu libm-2.17.so [.] __kernel_rem_pio2
+ 5.25% 5.22% stress-ng-cpu stress-ng [.] stress_cpu_matrix_prod
+ 4.91% 4.91% stress-ng-cpu stress-ng [.] hanoi
+ 4.62% 4.56% stress-ng-cpu libm-2.17.so [.] __ieee754_log_avx
+ 4.36% 4.32% stress-ng-cpu libm-2.17.so [.] __ieee754_exp_avx
- 找到相关进程,按回车键展开调用栈,就可以得到其调用关系,然后在具体分析其造成iowait升高的原因(可能是进程绕过系统缓存,对磁盘进行直接读写)
僵尸进程
pstree
处理僵尸进程问题,僵尸进程是因为父进程没有回收子进程的资源而出现的,那么要解决他们,就要找到其父进程,使用pstree命令:
#-a 表示输出命令行选项
#p表示pid
#s表示指定进程的父进程
[root@localhost ~]# pstree -aps 80363
systemd,1 --switched-root --system --deserialize 20
└─sshd,1501 -D
└─sshd,79264
└─sshd,79268
└─bash,79269
└─su,79308 - root
└─bash,79312
└─stress-ng,80362 -c 1
└─stress-ng-cpu,80363 -c 1
- 找到其父进程80362,就可以去针对检查代码是有问题没了
网友评论