进程在正常工作过程中,会占用一定的 CPU 和内存资源。如果占用过高的 CPU 和内存资源,则有可能是进程出现异常情况,并且可能会影响其他重要进程的正常运行。因此监控进程性能并在发现异常情况的时候自动做出反应,例如 kill 掉该进程、修改进程优先级或者发送预警信息给管理员,这将会给系统管理工作带来很大的帮助。
脚本 CheckProcPerformance 可以实现对进程性能自动化监控的功能,在发现进程 CPU 或者内存资源超出预定义的阈值时,执行指定的操作。用户还可以根据自己的需求,修改该代码,以实现更加复杂的监控功能。默认的定义阈值的文件是 /root/ProcAction,该文件也可以通过参数指定。该脚本在 RedHatEL-Server 5.3、SLES 10 SP2 操作系统上测试通过,可以正常执行,使用 perl 的版本为 v5.8.8。由于该脚本使用 top 命令获取进程性能信息,因此该脚本只适用于 Linux 操作系统,不适用于 AIX 操作系统。
清单 9. /root/CheckProcPerformance 文件内容
#!/usr/bin/perl use strict; my $ProcActionFile = $ARGV[0]; if( $ProcActionFile eq "" ) { $ProcActionFile = "/root/ProcAction"; } # 获取定义阈值文件的信息 my @ProcActionTable = &GetProcAction($ProcActionFile); # 获取 top 信息,提取 COMMAND,%CPU,%MEM 三列信息 my %TopInfoTable = &GetTopInfo; foreach my $line(@ProcActionTable) { chomp ($line); my @ActionLine=split /,/,$line; my $value; #$ActionLine[0] 是 Command 名称 ;$value 是 $ActionLine[0] 进程所对应的 CPU% 和 #MEM% 值 if (defined($TopInfoTable{$ActionLine[0]})) { $value = $TopInfoTable{$ActionLine[0]}; } else { next; } #$ActionLine[1] 的值是 CPU 的阈值 ; $ActionLine[2] 的值是内存阈值 ; #$ActionLine[3] 的值是响应脚本的名称 # 如果 CPU% 或者 MEM% 超出阈值文件所定义的 CPU 或者内存阈值,将执行 #$ActionLine[3] 对应的响应脚本 if( $ActionLine[1] < $$value[0] || $ActionLine[2] < $$value[1] ) { # 将监控进程的名称,CPU 和内存利用率值作为参数传给响应脚本 # 使脚本能提供管理员更详细预警信息 system "$ActionLine[3] $ActionLine[0] $$value[0] $$value[1]"; } } # 获取 top 信息,提取 COMMAND,%CPU,%MEM 三列信息,并以 COMMAND 为 key,#[%CPU,%MEM] 为 value,存入 Hash 表中 sub GetTopInfo { my @TopInfo = `top -n 1 | awk {'print \$13\" \"\$10\" \"\$11'}`; # 去掉 top 命令所显示的系统摘要信息部分 for( my $i=0; $i<7; $i++ ) { shift( @TopInfo ); } my %TopTable; foreach my $topitem (@TopInfo) { my @pair = split /\s+/,$topitem; $TopTable{$pair[0]} = [$pair[1], $pair[2]]; } return %TopTable; } # 获取 ProcAction 信息,将非注释的行存入数组中, sub GetProcAction { my ($file) = @_; unless(open(TABF, $file)) { print "Can't open file '$file'.\n"; exit 1; } my @table; foreach my $line (<TABF>) { chomp($line); if(!($line =~ /^#/) ) { push(@table, $line); } } return @table; close TABF; }
为了实现自定义进程性能监控的功能,我们创建一个操作定义文件,该文件定义了要进行监控的进程名称,CPU 和内存的阈值,以及 CPU 和内存利用率超过阈值时采取的操作。这里我们将该文件命名为 /root/ProcAction,该文件适用于 Linux 和 AIX 操作系统。本实例中列出了要进行性能监控的三个进程 init、kthread 以及 migration,其中内容和格式如下所示:
清单 10. /root/ProcAction 文件内容
#command,%cpu,%memory,action init,20,10,/root/action2 kthread,5,10,/root/action2 migration,15,20,/root/action2 Java,10,10,/root/action2
以第一行内容为例,表示我们要监控 init 进程,当该进程的 CPU 利用率达到 20%或者内存利用率达到 10% 的时候,运行脚本 /root/action2 进行响应。
其中 /root/action2 脚本的内容如下所示,用户也可以根据需求进行扩充和改变。
#!/bin/bash echo "The Process $1 Consumed too much CPU or Memory Resource:%CPU = $2% %MEM = $3%" | mail -s "Warning for Process $1" root在这个脚本里面,我们只做了简单的操作,发送监控进程的名称以及该进程的 CPU 和内存利用率给 root 用户。其中 $1,$2,$3 分别是 监控进程的名称,CPU 利用率和内存利用率的值。
我们的进程性能自动化监控脚本就是要监控 /root/ProcAction 文件中定义的进程,通过 top 获取到要监控的进程当前的 CPU 和内存利用率,然后将其与 /root/ProcAction 中定义的阈值进行比较,如果超出阈值,则发送警告邮件给 root 用户。
为了实现自动化的性能监控,我们利用系统的 cron 服务。使用命令“crontab -e”编辑 crontab,添加一个条目。
在 Linux 操作系统上添加一条 crontab 条目,表示每隔两分钟运行一次 CheckProcPerformance 脚本,内容如下所示:
清单 12. Linux crontab 新添加的内容
*/2 * * * * /root/CheckProcPerformance >> /root/checkprocperformance.log 2>&1
保存退出之后,可以用“crontab -l”查看,确保任务添加成功。
这里我们定义表示每隔两分钟运行一次 CheckProcPerformance 脚本,并将其输出存储在 /root/ checkprocperformance.log 文件中。用户可以根据自己的需求修改脚本运行的间隔时间。以上步骤完成后,就可以实现对进程性能的自动化监控了。
就我们这个例子来说,如果没有错误信息,checkprocperformance.log 日志中不会有信息保存,预警信息将会作为邮件发送给 root 用户。在测试的时候,java 进程占用的 CPU 值超过阈值,因此 root 用户收到一封标题为 Warning for Process java 的邮件:
清单 13. 预警邮件内容
From root@hv4plus_lpar2.ppd.pok.ibm.com Wed Jun 3 08:52:52 2009 X-Original-To: root Delivered-To: root@hv4plus_lpar2.ppd.pok.ibm.com Date: Wed, 03 Jun 2009 08:52:52 -0400 To: root@hv4plus_lpar2.ppd.pok.ibm.com Subject: Warning for Process java User-Agent: nail 11.25 7/29/05 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: root@hv4plus_lpar2.ppd.pok.ibm.com (root) The Process java Consumed too much CPU or Memory Resource:%CPU = 15% %MEM = 1.3%