先来看ps命令,通过ps -aux 可以查看到进程的CPU和MEM等信息:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 191808 3764 ? Ss 2018 2:44 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
root 2 0.0 0.0 0 0 ? S 2018 0:02 [kthreadd]
root 3 0.0 0.0 0 0 ? S 2018 5:23 [ksoftirqd/0]
root 5 0.0 0.0 0 0 ? S< 2018 0:00 [kworker/0:0H]
root 7 0.0 0.0 0 0 ? S 2018 0:00 [migration/0]
root 22056 0.1 2.0 750304 20340 ? Ssl 9月07 3:07 /usr/local/cloudmonitor/CmsGoAgent.linux-amd64
......#后面内容省略
这里我们单独取PID为22056的CmsGoAgent进程的CPU和MEM信息
命令:ps -o %cpu %,mem -p 22056
[16210504@izuf60jasqavbxb9efockpz ~]$ ps -o %cpu,%mem -p 22056
%CPU %MEM
0.1 2.0
由上面的结果可以看到成功拿出了结果,但是这个结果其实是不准确的,使用man ps命令,查看ps统计信息的说明如下:
%cpu %CPU cpu utilization of the process in "##.#" format. Currently, it is the CPU time used divided by the time the process has been running (cputime/realtime ratio), expressed as a percentage. It will not add up to 100% unless you are lucky.
(alias pcpu).
%mem %MEM ratio of the process's resident set size to the physical memory on the machine, expressed as a percentage. (alias pmem).
我们可以看到ps命令统计CPU的信息是拿CPU使用的时间除以进行总运行的时间(cputime/realtime ratio),这样就有可能出现,CPU在某个时间里利用率很高,但是因为进程已经运行了很久了,导致实际算出来的值依然是很小的,影响结果的判断,通常我们关注的是CPU在连续的变化情况,也就是需要CPU的切片信息;
这个时候我们想要即使的统计信息就需要使用top命令了:
[16210504@izuf60jasqavbxb9efockpz ~]$ top
top - 23:03:54 up 316 days, 13:52, 13 users, load average: 0.00, 0.01, 0.05
Tasks: 159 total, 1 running, 113 sleeping, 45 stopped, 0 zombie
%Cpu(s): 0.3 us, 0.7 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1016396 total, 434728 free, 133020 used, 448648 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 710848 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22056 root 20 0 750304 20472 5612 S 0.3 2.0 3:23.00 CmsGoAgent.linu
1 root 20 0 191808 3764 1436 S 0.0 0.4 2:44.29 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:02.10 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 5:23.84 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
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 42:39.12 rcu_sched
先过滤出PID为22056的CmsGoAgent进程的CPU和MEM信息
命令:top -b -p 22056 -d 1
-b : 批处理模式,可以把输出导给下一个进程
-p : 打印某一个进程
-d 1 : 每隔1秒打印一次
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -d 1
top - 23:14:52 up 316 days, 14:03, 10 users, load average: 0.00, 0.01, 0.05
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.5 us, 2.5 sy, 0.0 ni, 94.9 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1016396 total, 444484 free, 122968 used, 448944 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 721340 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22056 root 20 0 750304 20472 5612 S 0.0 2.0 3:24.04 CmsGoAgent.linu
top - 23:14:53 up 316 days, 14:03, 10 users, load average: 0.00, 0.01, 0.05
Tasks: 1 total, 0 running, 1 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 : 1016396 total, 444484 free, 122968 used, 448944 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 721340 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22056 root 20 0 750304 20472 5612 S 0.0 2.0 3:24.04 CmsGoAgent.linu
......#后面的内容省略
#不用-b命令的效果(进入交互模式):
16210504@izuf60jasqavbxb9efockpz ~]$ top -p 22056 -d 1
top - 23:18:05 up 316 days, 14:07, 10 users, load average: 0.13, 0.04, 0.05
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.0 sy, 0.0 ni, 99.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1016396 total, 444360 free, 123004 used, 449032 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 721304 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22056 root 20 0 750304 20472 5612 S 0.0 2.0 3:24.37 CmsGoAgent.linu
...#中间不会输出任何内容...
[16210504@izuf60jasqavbxb9efockpz ~]$
-
现在利用top命令来完成性能数据CPU、MEM信息的需求:
需求:统计进程10次的CPU和MEM的变化情况并输出平均值 预计效果:
CPU MEM
0.1 2.0
0.1 2.1
...#共统计10次
-----
0.13 2.4 #这里是平均值
实现:
每隔1秒打印一次进程信息,共打印10次,过滤出只包含进程信息的行:
命令:top -b -p 22056 -n 10 -d 1 | grep 22056
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056
22056 root 20 0 750304 20476 5616 S 0.0 2.0 3:26.70 CmsGoAgent.linu
22056 root 20 0 750304 20476 5616 S 0.0 2.0 3:26.70 CmsGoAgent.linu
22056 root 20 0 750304 20476 5616 S 0.0 2.0 3:26.70 CmsGoAgent.linu
......#共打印出10行
利用awk命令分别取出第9,第10段信息,对应着CPU和MEM,并用BEGAIN命令先打印出头信息
命令:top -b -p 22056 -n 10 -d 1 | grep 22056 | awk BEGAIN{print "CPU%","MEM%"}
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}'
CPU% MEM%
现在出现了一个现象,awk切片后的信息没有被实时打印出来,在大概过了10秒后,所有的信息被一起打印出来如下:
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}'
CPU% MEM%
#10秒后所有信息被一起打印
0.0 2.0
1.0 2.0
1.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
这里要先引出另一个问题:grep和awk处于效率的考量,会缓存一批数据再输出到标准输出,就会导致即使满足匹配条件也不会即使打印出来,想要获取即时的信息,就需要使用grep --line-buffered,使grep不缓存信息,直接输出:
另外,由于最后还要算平均值,所以每次的数据都需要存在一个变量中
命令:top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}'
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}'
CPU% MEM%
0.0 2.0
0.0 2.0
0.0 2.0
1.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
最后,我们我们利用awk的END,来输出分隔符,并计算最终的平均值打印出来(其中的NR表示总行数)
命令:top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'
最终结果:
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 10 -d 1 | grep 22056 --line-buffered | awk 'BEGIN{print "CPU%","MEM%"}{print $9,$10}{cpu+=$9;mem+=$10}END{print "------";print cpu/NR,mem/NR}'
CPU% MEM%
0.0 2.0
0.0 2.0
0.0 2.0
1.0 2.0
0.0 2.0
0.0 2.0
0.0 2.0
1.0 2.0
0.0 2.0
0.0 2.0
------
0.2 2
也可以即使打印平均值信息,并用OFS指定制表符的方式进行格式化输出:
命令:top -b -p 22056 -n 20 -d 1 | grep --line-buffered 22056 | awk 'BEGIN{OFS="\t";print "cpu","mem","avgc","avgm"}{c+=$9;m+=$10;print $9,$10,c/NR,m/NR}'
[16210504@izuf60jasqavbxb9efockpz ~]$ top -b -p 22056 -n 20 -d 1 | grep --line-buffered 22056 | awk 'BEGIN{OFS="\t";print "cpu","mem","avgc","avgm"}{c+=$9;m+=$10;print $9,$10,c/NR,m/NR}'
cpu mem avgc avgm
0.0 2.0 0 2
0.0 2.0 0 2
0.0 2.0 0 2
0.0 2.0 0 2
0.0 2.0 0 2
0.0 2.0 0 2
0.0 2.0 0 2
0.0 2.0 0 2
2.0 2.0 0.222222 2
0.0 2.0 0.2 2
0.0 2.0 0.181818 2
0.0 2.0 0.166667 2
0.0 2.0 0.153846 2
0.0 2.0 0.142857 2
0.0 2.0 0.133333 2
0.0 2.0 0.125 2
0.0 2.0 0.117647 2
0.0 2.0 0.111111 2
0.0 2.0 0.105263 2
0.0 2.0 0.1 2