本文涉及一些在Linux系统中进行资源监控的方法,其目的是为了在实际工作中监控系统的资源使用情况。
问题提出 自上个月开始,断断续续排查了几个疑难 bug,都是在生产环境发现的,兹事体大,必须解决,但限于能力和环境,有的bug并没有即时解决,但总算在一定期限内完成任务,由于时间紧,当时并没有详细记录过程,但过后回想,还是要做些经验总结。本文从进程占用内存脚本开始,对 Linux 资源使用情况的监控展开研究,以方便日后使用。
监控CPU和内存占用最多的十个进程 Linux 系统一般使用 ps 命令查看进程资源使用情况,其输出结果如下:
1 2 3 4 5 $ ps aux | head -n 4 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.1 191136 4172 ? Ss 14:51 0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 root 2 0.0 0.0 0 0 ? S 14:51 0:00 [kthreadd] root 3 0.1 0.0 0 0 ? S 14:51 0:02 [ksoftirqd/0]
从输出结果可以看出有CPU、内存、进程ID、进程名称等信息,其中CPU和内存的数值为百分比。
由此可知核心命令描述如下:
通过 ps 命令查看进程CPU、内存占用情况,再分别按CPU、内存数值倒序排序,再取前面10个即可。
查看内存占用最多的十个进程命令如下:
1 ps aux | grep -v PID | sort -rn -k +4 | head -n10
解释:
grep -v PID
为去掉带 PID 字样的一行,此处表示标题。
sort -rn -k +4
,-k +4 表示按第4列(即内存)内容排序,-rn 表示按数值倒序排序。
head -n10
表示取前面的10个,亦即占用内存最多的10个进程。
类似地,对于CPU占用情况,只需要将上面+4
改为+3
即可,因CPU占用百分比位于第三列。
监控指定进程的内存 该脚本是为了应付之前某进程内存泄漏的问题的,完整脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # !/bin/bash PROCESS=foobar LOGFILE="memlog.txt" # !/bin/bash # for ((;;)) # while [ 1 ] while : do PID=$(ps aux | grep $PROCESS | grep -v 'grep' | awk '{print $2;}') if [ "$PID" != "" ]; then echo `date +'%Y-%m-%d %H:%M:%S'` >> "$LOGFILE" MEM=$(ps aux | grep $PROCESS | grep -v 'grep' | awk '{print $5;}') MEM="ps mem: "$MEM RSS=$(cat /proc/$PID/status | grep RSS) echo $PROCESS $MEM $RSS >> "$LOGFILE" fi echo "System memory info: " $(cat /proc/meminfo | grep -E 'MemTotal|MemFree|Cached' |grep -v SwapCached|xargs) >> "$LOGFILE" echo "-------------" >> "$LOGFILE" sleep 5 done
注释如下:
由于要监控某一进程,因此需先指定进程名称。
再从 ps 列表中查询其 PID 和 内存
再由 PID 查询其常驻内存大小,该值在/proc/<PID>/status
文件中。
脚本每隔5秒输出一次信息,有时内存泄漏量较小,一般观察数小时、半天可以得到结果。确定存在内存泄漏情况时,再深入代码排查。该脚本对占用内存大小并不做严格计算,因为只是观察内存使用是否稳定,或是否持续增长,是否有跳变。就当时监控情况下,该进程下载文件时内存占用突增,过后恢复稳定状态,但保持几分钟十多KB增长的态势,因此判定内存泄漏。
判断磁盘占用情况 本脚本用于磁盘空间使用情况的监控。机制如下:
指定监控目录,指定空间使用百分比的阈值,当超过时,再删除。根据经验,一般超过 85%~90%时即可删除。该脚本可使用定时任务执行,根据磁盘使用空间,可半天或一天执行一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 # !/bin/sh # 前提:已挂载目录 mount_dir=/mnt/hgfs percent_in=85 file_del=1000 count_del=10 # 如果不存在目录,退出 if [ ! -d $mount_dir ]; then echo $mount_dir "not found, quit" exit fi percent=`df -h | grep $mount_dir | awk '{print $5}' | tr -d '%'` dev_file=`df -h | grep $mount_dir | awk '{print $1}'` file_count=`ls -l $mount_dir | wc -l` echo $percent $percent_in # 当空间占用百分比大于某个指定值时,删除目录前指定的数量 if [ $percent -ge $percent_in ];then echo "need to remove file! occupy" $percent"%" "of" $dev_file #cd $mount_dir #file=`ls | sort | head -$file_del` #rm $file #cd - else echo "no need to remove file" fi # 按文件数量判断,用于文件体积小但数量大的情况,因其会占用文件索引 # if [ $file_count -ge $count_del ];then # echo "need to remove file! occupy total" $count_del "files of" $dev_file #cd $mount_dir #file=`ls | sort | head -$file_del` #rm $file #cd - # else # echo "no need to remove file" # fi # file=`ls | sort | head -$file_del ` # echo $file echo "comand complete at" date echo "======================================"
进阶 可在脚本中添加邮件通知功能(可用其它程序实现),当出现异常或有重大事件发生时——如CPU占用达100%或删除文件时,不过目前暂未有时间着手。