工作中會遇到判斷服務器是否存活的場景,比如:批量重啟服務器后,各宿主機或虛擬機是否啟動成功。
檢測服務器是否存活的原理很簡單:先檢查服務器是否通(ping);如果不通則檢查服務器上的服務是否通,如果服務也不通,則說明這台服務器沒有開啟。可以使用的工具有:ping、telnet、nmap或者tcping等。
nmap功能強大,用處廣泛;tcping可以在服務器禁ping的情況下檢查機器是否存活(比如windows機器默認就是禁ping的)。在這里,我用的是ping和telnet組合。
關於ping工具,合理的使用相關參數比較有利於排查問題,比如:"-c"參數可以用來限制發送ping多少個包,"-i"參數可以用來限制ping的頻率等。舉例:
ping -c2 -i0.02 www.baidu.com > /dev/null 2>&1
上一段代碼意思為:以0.02秒的間隔時間ping www.baidu.com 2次,並將結果(正確或錯誤)引入到“黑洞”(丟棄),合理的使用參數可以幫助我們快速判斷目標主機是否可達。當然,會有人問:你將測試結果引入到黑洞,我怎么知道目標主機是通還是不通呢?這個時候可以通過判斷操作狀態得知,命令為:
echo $?
如果上面的結果返回值為0,說明www.baidu.com可達,否則www.baidu.com可能不通,需要進行下一步再判斷。有人說,通過手動執行命令麻煩,可否再精巧些?那就寫成腳本吧,如下:
#!/bin/bash # test. ping -c2 -i0.02 www.baidu.com > /dev/null 2>&1 if [ $? -eq 0 ];then echo "Host can access ...." else ... fi
解釋上面那段腳本,如果主機不通,則執行后續動作,這些后續動作放在"else"代碼塊中,后續動作可以使用nmap、telnet等工具,這里介紹telnet。
有人會說,telnet容易,如果telnet程序一直卡在那里則說明服務器端口不通,然后通過“CTRL+c”終止就行了,但是怎樣在腳本中使用telnet呢?簡單,通過Linux的管道功能(“|”),可以讓腳本沉睡一段時間,這段時間內telnet執行任務,待沉睡時間到期則終止telnet程序。話雖如此,怎樣實現呢?如下:
(sleep 1;) | telnet www.baidu.com 80
判斷某台服務器是否存活,可以先ping IP,再telnet port,如果是測試一個IP,則可將腳本寫成如下:
#!/bin/bash # test. host= www.baidu.com port=80 telnet_file=/tmp/telnet_file.txt ping -c2 -i0.02 $host > /dev/null 2>&1 if [ $? -eq 0 ];then echo "$host can access ...." else (sleep 1;) | telnet $host $port > $telnet_file grep -B 1 \] $telnet_file > /dev/null 2>&1 if [ $? -eq 0 ];then echo "$host can access ..." else echo "$host can not access !!!"
fi fi
上面的腳本是針對一個IP進行判斷,說實話如果是判斷一台服務器是否可達的話直接終端敲命令就知道了,不需要“大費周折”寫腳本了,但是如果同時測試多台機器就需要用到腳本了。對於編寫批量判斷多台主機是否可達的腳本,只需要將上述思路稍作整理,靈活使用linux基礎命令即可實現。當然,如果目標機器非常多的情況下,推薦使用ansible或者saltstack,或者干脆寫個python多進程的腳本去判斷。
下面貼出我之前基於ping和telnet工具寫的腳本,大致原理和上面講述的相似,在執行腳本前,請先編輯服務器配置文件。
執行腳本:
renxiaowei$ cat check.sh #!/bin/bash # 功能:一鍵檢測宿主機、虛擬機是否存活 # 作者:任小為 # 版本:v1.0 file=server.txt result_base=/tmp/check_host_net rm -rf $result_base mkdir -p $result_base super_host(){ super_ip_list=${result_base}/super_ip_list.txt super_alive=${result_base}/super_alive.txt super_die=${result_base}/super_die.txt super_telnet=${result_base}/super_telnet.txt echo "" echo -e "\033[44;36m檢測宿主機是否存活... \033[0m" egrep -v "#|^$" $file | awk '{print $1,$2}' | uniq > $super_ip_list count=0 for ip in $(cat ${super_ip_list} | awk '{print $1}');do let count++ echo "count=$count" ping -c 2 -i 0.02 $ip > /dev/null 2>&1 if [ $? -eq 0 ];then echo $ip >> ${super_alive} else super_port=`grep $ip ${super_ip_list} | awk '{print $2}'` (sleep 1;) | telnet $ip ${super_port} >> ${super_telnet} fi done if [ -e ${super_telnet} ];then super_ip=${result_base}/super_ip.txt cat ${super_ip_list} | awk '{print $1}' > ${super_ip} cat ${super_telnet} | grep -B 1 \] | grep [0-9] | awk '{print $3}' | cut -d '.' -f 1,2,3,4 >> ${super_alive} cat ${super_ip} ${super_alive} | sort | uniq -u > ${super_die} fi echo "" echo -e "\033[32;49;1m存活的宿主機: \033[31;49;0m" echo -e "`cat ${super_alive}`\n" if [ -s ${super_die} ];then echo -e "\033[31;49;1m檢測不通的宿主機:\033[31;49;0m" echo -e "\033[31;49;1m`cat ${super_die}`\033[31;49;0m\n" else echo -e "\033[44;36m所有宿主機都存活.\033[0m\n" fi } sub_host(){ sub_ip_list=${result_base}/sub_ip_list.txt sub_alive=${result_base}/sub_alive.txt sub_die=${result_base}/sub_die.txt sub_telnet=${result_base}/sub_telnet.txt echo "" echo -e "\033[44;36m檢測虛擬機是否存活... \033[0m" egrep -v "#|^$" $file | awk '{print $3,$4}' | uniq > $sub_ip_list sub_count=0 for sub_ip in $(cat ${sub_ip_list} | awk '{print $1}');do let sub_count++ echo "count=${sub_count}" ping -c 2 -i 0.02 ${sub_ip} > /dev/null 2>&1 if [ $? -eq 0 ];then echo ${sub_ip} >> ${sub_alive} else sub_port=`grep ${sub_ip} ${sub_ip_list} | awk '{print $2}'` (sleep 1;) | telnet ${sub_ip} ${sub_port} >> ${sub_telnet} fi done if [ -e ${sub_telnet} ];then sub_ip=${result_base}/sub_ip.txt cat ${sub_ip_list} |awk '{print $1}' > ${sub_ip} cat ${sub_telnet} | grep -B 1 \] | grep [0-9] | awk '{print $3}' | cut -d '.' -f 1,2,3,4 >> ${sub_alive} cat ${sub_ip} ${sub_alive} | sort | uniq -u > ${sub_die} fi echo "" echo -e "\033[32;49;1m存活的虛擬機: \033[31;49;0m" echo -e "`cat ${sub_alive}`\n" if [ -s ${sub_die} ];then echo -e "\033[31;49;1m檢測不通的虛擬機:\033[31;49;0m" echo -e "\033[31;49;1m`cat ${sub_die}`\033[31;49;0m\n" else echo -e "\033[44;36m所有虛擬機都存活.\033[0m\n" fi } case $1 in super) super_host ;; vm) sub_host ;; help) echo "" echo "`grep "功能" $file`" echo "super選項代表檢測宿主機;" echo -e "vm選項代表檢測虛擬機.\n" ;; *) echo "" echo -e $"Usage: sh $0 { super | vm | help }\n" esac exit 0
服務器配置文件格式:
renxiaowei$ cat server.txt #功能:用於一鍵檢測宿主機、虛擬機是否存活的文件 #格式:vm宿主機 ------ 宿主機管理端口 ---- 虛擬機 ---- 虛擬機管理端口 192.168.2.2 80 192.168.2.50 22 192.168.2.3 80 192.168.2.51 22 192.168.3.2 80 192.168.3.52 22
請將腳本、服務器配置文件放在同一個目錄下。
腳本執行方式:chmod + x check.sh && ./check.sh [super|vm|help] 或者 sh check.sh [super|vm|help] 。
腳本參數“super”意為宿主機檢測;參數“vm”意為虛擬機檢測。