簡介:本文是 Unix/Linux 系統管理自動化系列中的一篇,主要講述如何實現自動化監控進程狀態和 性能並及時通知系統管理員。
進程監控是 Unix/Linux 系統管理中一個非常重要的組成部分。它可以監控進程狀態、進程的 CPU 利 用率等信息,並且可以在發現進程出現異常情況的時候,發送告警信息給系統管理員或者做出指定的反應 。我們可以使用系統進程監控信息進行合理的進程調度從而優化系統性能,或者根據這些信息調整系統的 行為。
不同的操作系統監控進程的命令可能略有不同。本文將介紹 Unix/Linux 操作系統進程管理命令及相 關信息,並論述 Unix/Linux 操作系統上進程監控的自動化腳本實現。
Unix/Linux 進程管理相關命令介紹
進程是操作系統用於控制系統資源使用的實體。Unix/Linux 進程管理相關的命令主要有以下幾個,在 後面的腳本實現中會用到部分命令。
顯示進程屬性命令
ps 命令:該命令是最基本同時也是非常強大的進程查看命令,用於報告進程標識、用戶、CPU 時間消 耗以及其他屬性。利用它可以確定有哪些進程正在運行及運行的狀態、進程是否結束、進程有沒有僵死、 哪些進程占用了過多的資源等。ps 命令可以監控後台進程的工作情況,因為後台進程是不和屏幕鍵盤這 些標准輸入 / 輸出設備進行通信的,如果需要檢測其情況,可以使用 ps 命令。
單獨使用 ps 命令所看到的進程列表,都是在前台執行的進程,但並非所有進程都在前台執行,也有 不少進程隱藏在後台執行。使用命令 ps -e 可以顯示所有進程。
進程性能檢測命令
top 命令:Linux 使用 top 命令來顯示 CPU 占用率為前幾位的進程。該命令可以按 CPU 使用率、內 存使用率、執行時間對任務進行排序,而且該命令的很多特性都可以通過交互式命令或者在個人定制文件 中進行設定。top 主要字段的含義如下:
表 1. top 字段含義
列名 含義 PID 進程 ID USER 進程所有者的用戶名 PR 任務優先級 NI nice 值。數值越小表示優先級越高,數值越大表示優先級越低 VIRT 進程使用的虛擬內存總量,單位:kb。VIRT=SWAP+RES RES 進程使用的、未被換出的物理內存大小,單位:kb。RES=CODE+DATA SHR 共享內存大小,單位:kb S 進程狀態。
topas 命令:AIX 使用 topas 命令在字符終端上報告有關本地系統上的活動的至關重要的統計信息, 包括顯示 CPU 占用率為前幾位的進程。topas 命令以缺省的兩秒間隔從系統中提取並顯示統計信息。通 過命令 topas -P 可以進入 topas 的 process 子部分,顯示活動進程的列表。各進程將按它們在監視間 隔期間的 CPU 使用率進行排序。topas 針對每個進程所顯示的字段含義如下:
表 2. topas 字段含義
列名 含義 Name 在該進程中執行的可執行程序的名稱。此名稱將剝離任何路徑控制進程爭用 CPU 的優先級級別的命令
nice 命令:nice 命令允許您以比命令的正常優先級更低的優先級運行命令。
語法:nice [ - Increment| -n Increment ] Command [ Argument ... ]
如果您沒有指定 Increment 值,nice 命令缺省為遞增值 10。您必須有 root 用戶權限以在更高的優 先級運行命令。進程的優先級通常被稱作它的 nice 值。Linux 操作系統的 nice 值范圍是 -20 到 19, 19 是最低優先級。AIX 操作系統 nice 值的范圍是 0 到 39,39 是最低優先級。如果您沒有適當的權限 就試圖增加命令的優先級,nice 命令不會返回錯誤消息。相反,命令的優先級不會更改,並且系統以它 通常的優先級啟動命令。
renice 命令:renice 命令改變系統中已經在運行的一個或多個進程的 nice 值,因此改變了優先級 。進程可由進程標識、進程組標識或擁有該進程的用戶名識別。如果不具有 root 用戶權限,則僅可以重 新設置自己擁有的進程的優先級。
終止進程的命令
kill 命令:kill 命令發送一個信號(缺省,SIGTERM 信號)到一個正運行的程序。缺省操作一般是 停止進程。root 用戶可用 kill 命令來停止任何進程。如果不是 root 用戶,必須已經啟動了要停止的 進程。
進程定時啟動命令 crontab
為了定期執行命令,可以利用 crontab 定義命令執行的間隔和順序。crontab 命令用於提交、編輯、 列出或刪除 cron 作業。一個 cron 作業是一個命令,其運行是由 cron 守護程序在規則的調度間隔執行 的。要編輯提交一個 cron 作業,可以使用 crontab -e 命令。crontab -e 命令調用一個編輯會話,允 許創建一個 crontab 文件。crontab 文件中的條目必須是一種 cron 守護程序可接受的格式。編輯完成 後,
RedHat 系統會自動在 /var/spool/cron 下生成一個與此用戶同名的文件,此用戶的 cron 信息都記 錄在這個文件中。
SUSE 系統會自動在 /var/spool/cron/tabs 下生成一個與此用戶同名的文件,此用戶的 cron 信息都 記錄在這個文件中。
AIX 系統會自動在 /var/spool/cron/crontabs 下生成一個與此用戶同名的文件,此用戶的 cron 信 息都記錄在這個文件中。
以 RedHat 操作系統為例,cron 服務每分鐘不僅要讀一次 /var/spool/cron 內的所有文件,還需要 讀一次 /etc/crontab,因此我們配置這個文件也能運用 cron 服務做一些事情。用 crontab 配置是針對 某個用戶的,而編輯 /etc/crontab 是針對系統的任務。此文件的文件格式如下:
清單 1. /etc/crontab 文件內容
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root // 如果出現錯誤,或者有數據輸出,數據作為郵件發給這個帳號
HOME=/ // 使用者運行的路徑
# run-parts
01 * * * * root run-parts /etc/cron.hourly // 每小時執行 /etc/cron.hourly 目錄下 的腳本
02 4 * * * root run-parts /etc/cron.daily // 每天執行 /etc/cron.daily 目錄下的腳 本
22 4 * * 0 root run-parts /etc/cron.weekly // 每星期執行 /etc/cron.weekly 目錄下 的腳本
42 4 1 * * root run-parts /etc/cron.monthly // 每月去執行 /etc/cron.monthly 目錄 下的腳本
列出用戶目前的 crontab 可以使用命令:crontab -l UserName
刪除用戶目前的 crontab 可以使用命令:crontab -r UserName
一個 crontab 文件包含若干個 cron 作業的條目。每個 crontab 文件條目包括 6 個字段,它們被空 格或制表符以以下格式分開:
minute hour day_of_month month weekday command
這些字段接收以下值:
表 3. 字段含義
字段 值 minute 0 到 59 hour 0 到 23 day_of_month 1 到 31 month 1 到 12 weekday 0 到 6(星期日到星期六) command shell 命令必須為每個字段指定一個值。除了 command 字段,這些字段可以包含以下內容:
指定范圍內的一個數。要在 5 月運行一個命令,在 month 字段指定 5。
兩個被破折號分開的數目表明了包含的范圍。要從星期二到星期五運行 cron 作業,把 2-5 放到 weekday 字段中。
由逗號隔開的數字列表。要在一月第一天和最後一天的運行命令,在 day_of_month 字段中可指定 1,31。
由兩個被破折號分開的數字組成的組合表明了包含的范圍,可與由逗號格開的數字列表一起使用。要 在一月的第 10 天到第 16 天和最後一天首次運行命令,應該在 day_of_month 字段中指定 1,10-16,31 。以上兩種也可組合使用。
*(星號),意味著所有的允許值。要每個小時運行一個作業,在小時字段指定一個星號。
Unix/Linux 進程管理自動化實現
在這篇文章裡,我們將給出兩個比較常見的進程自動化管理示范實例,分別用來進行進程狀態自動化 管理和進程性能監控自動化管理。用戶可以根據自身需求,在這些腳本的基礎上進行擴展,實現更加復雜 的管理功能。
實現這兩個自動化腳本,我們需要三個文件,主要腳本文件,實現進程自動化管理的主要程序;操作 定義文件,定義進程名稱以及相關信息和指定操作;用戶自定義的 action 文件,定義系統采取的一系列 操作。具體實現將在下面詳細描述。
進程狀態管理自動化實現
服務器中的一些服務進程可能不穩定,偶爾會異常終止,因此需要一個監控程序來對這些進程進行監 控,當發現被監控的服務進程異常終止時,將其重新啟動或者實行一系列操作。
該監控程序的基本實現思路是,編寫一個監控腳本,然後在系統的 crontab 中將該腳本配置為定期自 動執行(例如可以配置為每 2 分鐘執行一次),監控腳本通過監控服務進程的狀態來判斷服務進程是否 已終止,當監控條件成立時,執行指定的命令或者腳本。
本實例的具體實現方法如下:
腳本 CheckProcLive 實現了監控指定進程狀態並在發現進程終止時采取指定的響應操作的功能。該腳 本在 RedHatEL-Server 5.3、SLES 10 SP2 和 AIX 5.3 操作系統上測試通過,可以正常執行,使用 perl 的版本為 v5.8.8。默認情況下,保存進程名稱以及對應操作的操作定義文件為 /root/StartProc,該文 件位置也可以通過參數指定。代碼如下:
清單 2. /root/CheckProcLive 文件內容
#!/usr/bin/perl
use strict;
my $StartProcFile = $ARGV[0];
if( $StartProcFile eq "" )
{
$StartProcFile = "/root/StartProc";
}
my %StartProcHash = GetStartProc($StartProcFile);
my %PsHash = &GetPs;
while (my($key,$value) = each %StartProcHash)
{
if(!defined($PsHash{$key}))
{
system "$value";
}
}
# 獲取正在運行的進程命令,並將其存放在一個 Hash 表中,
# 其中 key 為命令名稱,值賦了同樣的一個數字 1,這個值沒有特殊含義和作用
sub GetPs
{
# 獲取 ps -e 的第四列,即包含命令的列
my @PsArray = `ps -e |perl -ane 'print "\$F[3]\n"'`;
my %PsHash;
foreach my $cmditem(@PsArray)
{
chomp($cmditem);
$PsHash{$cmditem} = 1;
}
return %PsHash;
}
# 獲取參數指定的或者程序默認的操作定義文件的信息,並將其中的信息存入 Hash 表中,其中 key 值是命令名稱
#value 是指發現進程終止時進行的相應操作。
sub GetStartProc
{
my ($file) = @_;
my $result;
my %startproctab;
unless(open(TABF, $file)) {
print "Can't open file '$file'.\n";
exit 1;
}
foreach my $line (<TABF>)
{
chomp($line);
#print "line = $line";
if(!($line =~ /^#/) && $line =~ /(\S+),(.+)\s*$/)
{
$startproctab{$1} = $2;
}
}
return %startproctab;
close TABF;
}
清單 2 中用到的操作定義文件是為了可以實現可定制的自動化進程監控,在檢測到進程終止的時候進 行指定的操作。在這裡我們定義了以下一個文件,/root/StartProc,由於第二列采取指定操作和操作系 統相關,因此該文件只可用於 Linux 操作系統,用戶要在 AIX 系統上使用,可以修改第二列操作的值, 使之適用於 AIX 系統即可。
清單 3. /root/StartProc 文件內容
# 各列的含義為:命令或者進程名稱,發現進程已經終止采取的指定操作
sshd,service sshd start
dhcpd,service dhcpd start
ftpd,/root/action1
第一列是在 ps -e 中所顯示的命令名稱,第二列是發現該進程終止之後需要采取的操作。該操作可以 是執行一個命令,也可以是執行一個響應腳本。響應腳本可以進行多個操作,例如重新啟動進程,並且發 送包含提示信息的郵件給管理員。
下面是一個響應腳本的簡單實例,僅實現發送郵件給 root 管理員的功能。
清單 4. /root/action1 文件內容
#!/bin/bash
echo "process ftpd is not running now" | mail -s "process status warning!" root
為了實現自動化的監控,我們需要利用系統的 cron 服務。使用命令“crontab -e”編輯 crontab,添加一個條目。
在 Linux 操作系統上添加一條 crontab 條目,表示每隔兩分鐘運行一次 CheckProcLive 腳本,內容 如下所示:
清單 5. Linux crontab 新添加的內容
*/2 * * * * /root/CheckProcLive >> /root/checkproclive.log 2>&1
在 AIX 操作系統上添加一條 crontab 條目,表示每隔兩分鐘運行一次 CheckProcLive 腳本,內容如 下所示:
清單 6. AIX crontab 新添加的內容
0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,
46,48,50,52,54,56,58 * * * * /root/CheckProcLive >> /root/checkproclive.log 2>&1
保存退出之後,可以用“crontab -l”查看,確保任務添加成功。
上面兩條 crontab 條目都表示每隔兩分鐘運行一次 CheckProcLive 腳本,並將其輸出存儲在 /root/checkproclive.log 文件中。用戶可以根據自己的需求修改腳本運行的間隔時間。cron 運行命令 時,其命令結果不會顯示在屏幕上,而是將輸出的結果通過郵件發給管理員,所以為了方便查詢命令執行 的結果,最好將輸出重定向到文件中。以上步驟完成後,就可以實現對進程狀態的自動監控了。
下面是在 /root/StartProc 中定義的進程都未啟動的情況下監控程序所記錄的日志信息。
清單 7. /root/checkproclive.log
Starting SSH daemon done
Starting DHCP server [chroot] done
同時因為 ftpd 服務沒有啟動,監控程序也執行了 /root/action1 腳本,因此 root 用戶的郵箱中會 收到一封標題為 process status warning!的預警郵件,如下所示:
清單 8. 預警郵件內容
From root@hv4plus_lpar2.ppd.pok.ibm.com Wed Jun 3 09:00:02 2009
X-Original-To: root
Delivered-To: root@hv4plus_lpar2.ppd.pok.ibm.com
Date: Wed, 03 Jun 2009 09:00:02 -0400
To: root@hv4plus_lpar2.ppd.pok.ibm.com
Subject: process status warning!
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)
process ftpd is not running now
進程性能監控自動化實現
進程在正常工作過程中,會占用一定的 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 腳本的內容如下所示,用戶也可以根據需求進行擴充和改變。
清單 11. /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%
小結
本文介紹了 Unix/Linux 上的進程監控命令和進程定時啟動命令,並通過兩個自動化監控腳本詳細介 紹了如何實現進程狀態和性能的自動化監控管理。監控系統進程會給系統管理員提供豐富的關於系統進程 運行的信息,自動化監控的實現更能為系統管理員在系統發生異常時采取迅速的措施提供了方便。