8.6 列出1小时内占用CPU最多的10个进程
CPU时间是一项重要的资源,有时我们需要跟踪某个时期内占用CPU周期最多的进程。在普通的桌面系统或膝上系统中,CPU处于高负荷状态也许不会引发问题。但对于需要处理大量请求的服务器来说,CPU是极其重要的资源。通过监视某个时期内CPU的使用情况,我们可以找出长期占用CPU的进程并对其进行优化,或是调试其他问题。这则攻略是一次有关进程监视与日志记录的实践。
8.6.1 新手上路
ps
命令用于收集系统中进程的详细信息。这些信息包括CPU使用情况、正在执行的命令、内存使用、进程状态等。记录在一小时内占用过CPU的进程,然后通过恰当地运用ps
以及文本处理就可以找出占用CPU最多的10个进程。关于ps
命令的更多细节,请参考第9章。
8.6.2 实战演练
让我们看看用于监视并计算一小时内CPU使用情况的shell脚本:
#!/bin/bash
#文件名: pcpu_usage.sh
#用途:计算1个小时内进程的CPU占用情况
SECS=3600
UNIT_TIME=60
#将SECS更改成需要进行监视的总秒数
#UNIT_TIME是取样的时间间隔,单位是秒
STEPS=$(( $SECS / $UNIT_TIME ))
echo Watching CPU usage... ;
for((i=0;i<STEPS;i++))
do
ps -eo comm,pcpu | tail -n +2 >> /tmp/cpu_usage.$$
sleep $UNIT_TIME
done
echo
echo CPU eaters :
cat /tmp/cpu_usage.$$ | \
awk '
{ process[$1]+=$2; }
END{
for(i in process)
{
printf("%-20s %s",i, process[i]);
}
}' | sort -nrk 2 | head
rm /tmp/cpu_usage.$$
#删除临时日志文件
输出如下:
- $ ./pcpu_usage.sh
- Watching CPU usage...
- CPU eaters :
- Xorg 20
- firefox-bin 15
- bash 3
- evince 2
- pulseaudio 1.0
- pcpu.sh 0.3
- wpa_supplicant 0
- wnck-applet 0
- watchdog/0 0
- usb-storage 0
8.6.3 工作原理
在上面的脚本中,主要的输入源是ps -eo comm,pcpu
,其中comm
表示命令名(command name),pcpu
表示CPU使用率(CUP usage in percent)。该命令输出所有进程名及CPU使用率。每个进程对应一行输出。因为需要监视一小时内CPU的使用情况,所以我们得在一个每次迭代时间为60秒的for
循环中不停地用ps -eo comm,pcpu | tail -n +2
来获取CPU的使用统计数据,并将这些数据添加到文件 /tmp/cpu_usage.$$ 中。60秒的迭代时间通过sleep 60
来提供。这就使得每一分钟执行一次ps
。
tail -n +2
用来将 ps
输出中的头部和 COMMAND %CPU
剥除。
cpu_usage.
中的 表示当前脚本的进程 ID。假设进程 ID为1345,那么在脚本执行时它会被替换成 /tmp/cpu_usage.1345。因为这是一个临时文件,所以我们把它放在 /tmp中。
统计文件在1小时后就准备妥当了,文件中包含了60项,分别对应每分钟的进程状态。然后用awk求出每个进程总的CPU使用情况。我们用了一个关联数组来统计CPU使用情况。其中进程名作为数组索引。最后根据总的CPU使用情况依数值逆序排序,并通过head
获得前10项。
8.6.4 参考
4.7节讲解了
awk
命令。3.14节讲解了
tail
命令。