https://www.jianshu.com/p/f76c54cd00fe
注:本文只是为了辅助自己分析而记录
首先我们来分析一下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
总结:
1、iowait太高,导致系统平均负载升高,达到了系统cpu的个数
2、僵尸进程在不断增多,说明有程序没能正确清理子进程的资源。
注:无法模拟上图的压力环境,所以只是介绍方法:
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
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
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