在伺服器營運過程中,經常需要對伺服器的各種資源進行監控,例如:CPU的負載監控,磁碟的使用率監控,進程數目監控等等,以在系統出現異常時及時警示,通知系統管理員。本文介紹在Linux系統下幾種常見的監控需求及其shell指令碼的編寫。
文章目錄:
1.Linux使用 Shell 檢查進程是否存在
2.Linux使用 Shell檢測進程 CPU 利用率
3.Linux使用 Shell檢測進程記憶體使用量量
4.Linux使用 Shell檢測進程控制代碼使用量
5.Linux使用 Shell查看某個 TCP 或 UDP 連接埠是否在監聽
6.Linux使用 Shell查看某個進程名正在啟動並執行個數
7.Linux使用 Shell檢測系統 CPU 負載
8.Linux使用 Shell檢測系統磁碟空間
9.總結
檢查進程是否存在
在對進程進行監控時,我們一般需要得到該進程的 ID,進程 ID 是進程的唯一標識,但是有時可能在伺服器上不同使用者下運行著多個相同進程名的進程,下面的函數 GetPID 給出了擷取指定使用者下指定進程名的進程 ID 功能(目前只考慮這個使用者下啟動一個此進程名的進程),它有兩個參數為使用者名稱和進程名,它首先使用 ps 尋找進程資訊,同時通過 grep 過濾出需要的進程,最後通過 sed 和 awk 尋找需要進程的 ID 值(此函數可根據實際情況修改,比如需要過濾其它資訊等)。
清單 1. 對進程進行監控
複製代碼 代碼如下:
function GetPID #User #Name
{
PsUser=$1
PsName=$2
pid=`ps -u $PsUser|grep $PsName|grep -v grep|grep -v vi|grep -v dbx\n
|grep -v tail|grep -v start|grep -v stop |sed -n 1p |awk '{print $1}'`
echo $pid
}
樣本示範:
1)來源程式(例如尋找使用者為 root,進程名為 CFTestApp 的進程 ID)
複製代碼 代碼如下:
PID=`GetPID root CFTestApp`
echo $PID
2)結果輸出
複製代碼 代碼如下:
11426
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:11426 為 root 使用者下的 CFTestApp 程式的進程 ID。
4)命令介紹
1. ps: 查看系統中瞬間進程資訊。 參數:-u< 使用者識別碼 > 列出屬於該使用者的程式的狀況,也可使用使用者名稱稱來指定。 -p< 進程識別碼 > 指定進程識別碼,並列出該進程的狀況。 -o 指定輸出格式 2. grep: 用於尋找檔案中符合字串的當前行。 參數:-v 反向選擇,亦即顯示出沒有 ‘搜尋字串' 內容的那一行。 3. sed: 一個非互動性文字編輯器,它編輯檔案或標準輸入匯出的檔案,一次只能處理一行內容。 參數:-n 讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。 p 標誌 列印匹配行 4. awk:一種程式設計語言,用於在 linux/unix 下對文本和資料進行處理。資料可以來自標準輸入、一個或多個檔案,或其它命令的輸出。它支援使用者自訂函數和動態Regex等先進功能,是 linux/unix 下的一個強大編程工具。它在命令列中使用,但更多是作為指令碼來使用。awk 的處理文本和資料的方式:它漸進式掃描檔案,從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行你想要的操作。如果沒有指定處理動作,則把匹配的行顯示到標準輸出 ( 螢幕 ),如果沒有指定模式,則所有被操作所指定的行都被處理。 參數:-F fs or –field-separator fs :指定輸入檔案折分隔字元,fs 是一個字串或者是一個Regex,如 -F:。
有時有可能進程沒有啟動,下面的功能是檢查進程 ID 是否存在,如果此進程沒有運行輸出:
複製代碼 代碼如下:
The process does not exist.
# 檢查進程是否存在
if [ "-$PID" == "-" ]
then
{
echo "The process does not exist."
}
fi
檢測進程 CPU 利用率
在對應用服務進行維護時,我們經常遇到由於 CPU 過高導致業務阻塞,造成業務中斷的情況。CPU 過高可能由於業務量過負荷或者出現死迴圈等異常情況,通過指令碼對業務進程 CPU 進行時時監控,可以在 CPU 利用率異常時及時通知維護人員,便於維護人員及時分析,定位,以及避免業務中斷等。下面的函數可獲得指定進程 ID 的進程 CPU 利用率。它有一個參數為進程 ID,它首先使用 ps 尋找進程資訊,同時通過 grep -v 過濾掉 %CPU 行,最後通過 awk 尋找 CPU 利用百分比的整數部分(如果系統中有多個 CPU,CPU 利用率可以超過 100%)。
清單 2. 對業務進程 CPU 進行即時監控
複製代碼 代碼如下:
function GetCpu
{
CpuValue=`ps -p $1 -o pcpu |grep -v CPU | awk '{print $1}' | awk - F. '{print $1}'`
echo $CpuValue
}
下面的功能是通過上面的函數 GetCpu 獲得此進程的 CPU 利用率,然後通過條件陳述式判斷 CPU 利用率是否超過限制,如果超過 80%(可以根據實際情況進行調整),則輸出警示,否則輸出正常資訊。
清單 3. 判斷 CPU 利用率是否超過限制
複製代碼 代碼如下:
function CheckCpu
{
PID=$1
cpu=`GetCpu $PID`
if [ $cpu -gt 80 ]
then
{
echo “The usage of cpu is larger than 80%”
}
else
{
echo “The usage of cpu is normal”
}
fi
}
樣本示範:
1)來源程式(假設上面已經查詢出 CFTestApp 的進程 ID 為 11426)
複製代碼 代碼如下:
CheckCpu 11426
2)結果輸出
複製代碼 代碼如下:
The usage of cpu is 75
The usage of cpu is normal
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:CFTestApp 程式當前的 CPU 使用為 75%,是正常的,沒有超過 80% 的警示限制。
檢測進程記憶體使用量量
在對應用服務進行維護時,也經常遇到由於記憶體使用量過大導致進程崩潰,造成業務中斷的情況(例如 32 位程式可定址的最大記憶體空間為 4G,如果超出將申請記憶體失敗,同時實體記憶體也是有限的)。記憶體使用量過高可能由於記憶體泄露,訊息堆積等情況,通過指令碼對業務進程記憶體使用量量進行時時監控,可以在記憶體使用量量異常時及時發送警示(例如通過簡訊),便於維護人員及時處理。下面的函數可獲得指定進程 ID 的進程記憶體使用量情況。它有一個參數為進程 ID,它首先使用 ps 尋找進程資訊,同時通過 grep -v 過濾掉 VSZ 行 , 然後通過除 1000 取以兆為單位的記憶體使用量量。
清單 4. 對業務進程記憶體使用量量進行監控
複製代碼 代碼如下:
function GetMem
{
MEMUsage=`ps -o vsz -p $1|grep -v VSZ`
(( MEMUsage /= 1000))
echo $MEMUsage
}
下面的功能是通過上面的函數 GetMem獲得此進程的記憶體使用量,然後通過條件陳述式判斷記憶體使用量是否超過限制,如果超過 1.6G(可以根據實際情況進行調整),則輸出警示,否則輸出正常資訊。
清單 5. 判斷記憶體使用量是否超過限制
複製代碼 代碼如下:
mem=`GetMem $PID`
if [ $mem -gt 1600 ]
then
{
echo “The usage of memory is larger than 1.6G”
}
else
{
echo “The usage of memory is normal”
}
fi
樣本示範:
1)來源程式(假設上面已經查詢出 CFTestApp 的進程 ID 為 11426)
複製代碼 代碼如下:
mem=`GetMem 11426`
echo "The usage of memory is $mem M"
if [ $mem -gt 1600 ]
then
{
echo "The usage of memory is larger than 1.6G"
}
else
{
echo "The usage of memory is normal"
}
fi
2)結果輸出
複製代碼 代碼如下:
The usage of memory is 248 M
The usage of memory is normal
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:CFTestApp 程式當前的記憶體使用量為 248M,是正常的,沒有超過 1.6G 的警示限制。
檢測進程控制代碼使用量
在對應用服務進行維護時,也經常遇到由於控制代碼使用 過量導致業務中斷的情況。每個平台對進程的控制代碼使用都是有限的,例如在 Linux 平台,我們可以使用 ulimit – n 命令(open files (-n) 1024)或者對 /etc/security/limits.conf 的內容進行查看,得到進程控制代碼限制。控制代碼使用過高可能由於負載過高,控制代碼泄露等情況,通過指令碼對業務進程控制代碼使用量進行時時監控,可以在異常時及時發送警示(例如通過簡訊),便於維護人員及時處理。下面的函數可獲得指定進程 ID 的進程控制代碼使用方式。它有一個參數為進程 ID,它首先使用 ls 輸出進程控制代碼資訊,然後通過 wc -l 統計輸出控制代碼個數。
複製代碼 代碼如下:
function GetDes
{
DES=`ls /proc/$1/fd | wc -l`
echo $DES
}
下面功能是通過上面的函數 GetDes獲得此進程的控制代碼使用量,然後通過條件陳述式判斷控制代碼使用是否超過限制,如果超過 900(可以根據實際情況進行調整)個,則輸出警示,否則輸出正常資訊。
複製代碼 代碼如下:
des=` GetDes $PID`
if [ $des -gt 900 ]
then
{
echo “The number of des is larger than 900”
}
else
{
echo “The number of des is normal”
}
fi
樣本示範:
1)來源程式(假設上面查詢出 CFTestApp 的進程 ID 為 11426)
複製代碼 代碼如下:
des=`GetDes 11426`
echo "The number of des is $des"
if [ $des -gt 900 ]
then
{
echo "The number of des is larger than 900"
}
else
{
echo "The number of des is normal"
}
fi
2)結果輸出
複製代碼 代碼如下:
The number of des is 528
The number of des is normal
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:CFTestApp 程式當前的控制代碼使用為 528 個,是正常的,沒有超過 900 個的警示限制。
4)命令介紹
wc: 統計指定檔案中的位元組數、字數、行數 , 並將統計結果顯示輸出。 參數:-l 統計行數。 -c 統計位元組數。 -w 統計字數。
查看某個 TCP 或 UDP 連接埠是否在監聽
連接埠檢測是系統資源檢測經常遇到的,特別是在網路通訊情況下,連接埠狀態的檢測往往是很重要的。有時可能進程,CPU,記憶體等處於正常狀態,但是連接埠處於異常狀態,業務也是沒有正常運行。下面函數可判斷指定連接埠是否在監聽。它有一個參數為待檢測連接埠,它首先使用 netstat 輸出連接埠佔用資訊,然後通過 grep, awk,wc 過濾輸出監聽 TCP 通訊埠的個數,第二條語句為輸出 UDP 連接埠的監聽個數,如果 TCP 與 UDP 連接埠監聽都為 0,返回 0,否則返回 1.
清單 6. 連接埠檢測
複製代碼 代碼如下:
function Listening
{
TCPListeningnum=`netstat -an | grep ":$1 " | \n
awk '$1 == "tcp" && $NF == "LISTEN" {print $0}' | wc -l`
UDPListeningnum=`netstat -an|grep ":$1 " \n
|awk '$1 == "udp" && $NF == "0.0.0.0:*" {print $0}' | wc -l`
(( Listeningnum = TCPListeningnum + UDPListeningnum ))
if [ $Listeningnum == 0 ]
then
{
echo "0"
}
else
{
echo "1"
}
fi
}
樣本示範:
1)來源程式(例如查詢 8080 連接埠的狀態是否在監聽)
複製代碼 代碼如下:
isListen=`Listening 8080`
if [ $isListen -eq 1 ]
then
{
echo "The port is listening"
}
else
{
echo "The port is not listening"
}
fi
2)結果輸出
複製代碼 代碼如下:
The port is listening
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:這個 Linux 伺服器的 8080 連接埠處在監聽狀態。
4)命令介紹
netstat: 用於顯示與 IP、TCP、UDP 和 ICMP 協議相關的統計資料,一般用於檢驗本機各連接埠的網路連接情況。 參數:-a 顯示所有連線中的 Socket。 -n 直接使用 IP 位址,而不通過網域名稱伺服器。
下面的功能也是檢測某個 TCP 或者 UDP 連接埠是否處在正常狀態。
複製代碼 代碼如下:
tcp: netstat -an|egrep $1 |awk '$6 == "LISTEN" && $1 == "tcp" {print $0}'
udp: netstat -an|egrep $1 |awk '$1 == "udp" && $5 == "0.0.0.0:*" {print $0}'
命令介紹
egrep: 在檔案內尋找指定的字串。egrep 執行效果如 grep -E,使用的文法及參數可參照 grep 指令,與 grep 不同點在於解讀字串的方法,egrep 是用擴充的Regex文法來解讀,而 grep 則用基本的Regex文法,擴充的Regex比基本的Regex有更完整的表達規範。
查看某個進程名正在啟動並執行個數
有時我們可能需要得到伺服器上某個進程的啟動個數,下面的功能是檢測某個進程正在啟動並執行個數,例如進程名為 CFTestApp。
複製代碼 代碼如下:
Runnum=`ps -ef | grep -v vi | grep -v tail | grep "[ /]CFTestApp" | grep -v grep | wc -l
檢測系統 CPU 負載
在對伺服器進行維護時,有時也遇到由於系統 CPU(利用率)負載 過量導致業務中斷的情況。伺服器上可能運行多個進程,查看單個進程的 CPU 都是正常的,但是整個系統的 CPU 負載可能是異常的。通過指令碼對系統 CPU 負載進行時時監控,可以在異常時及時發送警示,便於維護人員及時處理,預防事故發生。下面的函數可以檢測系統 CPU 使用方式 . 使用 vmstat 取 5 次系統 CPU 的 idle 值,取平均值,然後通過與 100 取差得到當前 CPU 的實際佔用值。
複製代碼 代碼如下:
function GetSysCPU
{
CpuIdle=`vmstat 1 5 |sed -n '3,$p' \n
|awk '{x = x + $15} END {print x/5}' |awk -F. '{print $1}'
CpuNum=`echo "100-$CpuIdle" | bc`
echo $CpuNum
}
樣本示範:
1)來源程式
複製代碼 代碼如下:
cpu=`GetSysCPU`
echo "The system CPU is $cpu"
if [ $cpu -gt 90 ]
then
{
echo "The usage of system cpu is larger than 90%"
}
else
{
echo "The usage of system cpu is normal"
}
fi
2)結果輸出
複製代碼 代碼如下:
The system CPU is 87
The usage of system cpu is normal
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:當前 Linux 伺服器系統 CPU 利用率為 87%,是正常的,沒有超過 90% 的警示限制。
4)命令介紹
vmstat:Virtual Meomory Statistics(虛擬記憶體統計)的縮寫,可對作業系統的虛擬記憶體、進程、CPU 活動進行監視。
參數: -n 表示在周期性迴圈輸出時,輸出的頭部資訊僅顯示一次。
檢測系統磁碟空間
系統磁碟空間檢測是系統資源檢測的重要部分,在系統維護維護中,我們經常需要查看伺服器磁碟空間使用方式。因為有些業務要時時寫話單,日誌,或者臨時檔案等,如果磁碟空間用盡,也可能會導致業務中斷,下面的函數可以檢測當前系統磁碟空間中某個目錄的磁碟空間使用方式 . 輸入參數為需要檢測的目錄名,使用 df 輸出系統磁碟空間使用資訊,然後通過 grep 和 awk 過濾得到某個目錄的磁碟空間使用百分比。
複製代碼 代碼如下:
function GetDiskSpc
{
if [ $# -ne 1 ]
then
return 1
fi
Folder="$1$"
DiskSpace=`df -k |grep $Folder |awk '{print $5}' |awk -F% '{print $1}'
echo $DiskSpace
}
樣本示範:
1)來源程式(檢測目錄為 /boot)
複製代碼 代碼如下:
Folder="/boot"
DiskSpace=`GetDiskSpc $Folder`
echo "The system $Folder disk space is $DiskSpace%"
if [ $DiskSpace -gt 90 ]
then
{
echo "The usage of system disk($Folder) is larger than 90%"
}
else
{
echo "The usage of system disk($Folder) is normal"
}
fi
2)結果輸出
複製代碼 代碼如下:
The system /boot disk space is 14%
The usage of system disk(/boot) is normal
[dyu@xilinuxbldsrv shell]$
3)結果分析
從上面的輸出可見:當前此 Linux 伺服器系統上 /boot 目錄的磁碟空間已經使用了 14%,是正常的,沒有超過使用 90% 的警示限制。
4)命令介紹
df:檢查檔案系統的磁碟空間佔用情況。可以利用該命令來擷取硬碟被佔用了多少空間,目前還剩下多少空間等資訊。 參數:-k 以 k 位元組為單位顯示。
總結
在 Linux 平台下,shell 指令碼監控是一個非常簡單,方便,有效對伺服器,進程進行監控的方法,對系統開發以及進程維護人員非常有協助。它不僅可以對上面的資訊進行監控,發送警示,同時也可以監控進程的日誌等等的資訊,希望本文對大家有協助。