1. 背景介紹
在日常運維工作中,網路連通性是確保系統穩定性和高可用性的關鍵因素之一。透過測試網路連通性,運維人員可以快速診斷網路問題,判斷系統與其他裝置或服務的連線狀態。這對於預防和處理網路故障至關重要。
本文將介紹如何編寫和使用一個簡單的運維指令碼,來自動化測試伺服器的網路連通性。
2. 目標描述
本文的目標是建立一個運維指令碼,用於測試伺服器之間的網路連線是否正常。該指令碼能夠:
- 檢查與目標IP或域名的連通性。
- 提供網路連通性測試的結果(如是否連線成功,響應時間等)。
- 對不同的網路故障型別進行簡單的錯誤提示,幫助快速定位問題。
3. 指令碼設計思路
在測試網路連通性時,我們通常會使用以下工具:
- Nc 命令:用來測試網路連線性,檢查目標主機是否可達。
- Traceroute 命令(可選):用於分析網路路由,幫助定位中斷的節點。
指令碼設計應簡潔明瞭,能夠透過引數傳遞目標IP或域名,並且輸出直觀的測試結果。
4. 指令碼示例
#!/bin/bash # checkConnectStatus.sh # 批次測試網路連通性指令碼 log_err() { printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: \033[31mERROR: \033[0m$@\n" } log_info() { printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: \033[32mINFO: \033[0m$@\n" } log_warning() { printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: \033[33mWARNING: \033[0m$@\n" } THREADS=5 # 等待佇列初始化 queue_init() { tmp="/tmp/$$.fifo" mkfifo $tmp exec 6<>$tmp rm -f $tmp for ((i = 1; i <= $THREADS; i++)); do echo done >&6 } init() { connectConfigDirPath="conf" if [ ! -d "$connectConfigDirPath" ];then mkdir $connectConfigDirPath fi connectFileName="${connectConfigDirPath}/connect.csv" if [ ! -f "$connectFileName" ];then echo "測試地址|測試結果|狀態" > $connectFileName fi # 檢查是否存在nc命令 if [ -n "$(rpm -qa | grep 'ncat')" ];then yum -y install nc > /dev/null 2>&1 if [ $? -ne 0 ];then log_err "[init] yum install nc failed! 請手動安裝nc命令" fi fi # 引數為空,列印使用方式 if [ $# -eq 0 ]; then usage fi while [[ $# -gt 0 ]]; do case $1 in --fileName) connectIpPortFileName=$2 shift shift ;; * | --help) usage ;; esac done } usage() { echo "Usage: $0 --fileName 填寫測試連通性檔案 " exit 1 } checkConnectToFile() { local url=$1 local ip=$(echo $url | awk -F":" '{print $1}') local port=$(echo $url | awk -F":" '{print $2}') local data=$(nc -zv -w 5 $ip $port 2>&1 | tr "\n" " ") local message="網路連通性正常" if [ -n "$(echo $data | grep 'Ncat: 0 bytes sent, 0 bytes received')" ];then log_info "[connect] url: $url data:[$data] msg: $message" else local message="網路連通性異常" log_err "[connect] url: $url data:[$data] msg: $message" fi # 將測試結果記錄到檔案中,因使用多執行緒檔案操作加鎖 { # 檔案執行過程加鎖,等待直到可以鎖定檔案 flock 002 # 結果記錄到檔案中 echo "$url|$data|$message" >> $connectFileName } 002>"${connectFileName}.lock" # 002是檔案描述符,此處用於解鎖 } readFileToConnect() { while read -r line;do local IPList=$(echo $line | awk -F"|" '{print $1}') local PortList=$(echo $line | awk -F"|" '{print $2}') local conncetHostPortArray=() # 配置資料處理 { # 多IP情況下 if [ -n "$(echo $IPList | grep ',')" ];then # 進行遍歷 IFS=',' read -r -a ipArray <<< "$IPList" for ip in ${ipArray[@]};do local strLength=$(echo -n "$ip" | wc -c) # 小於3則進行拼接 if [ $strLength -le 3 ];then newIP=${startIP:0:-$strLength}$ip else startIP=$ip # 最終IP地址 newIP=$ip fi if [ -n "$(echo $PortList | grep ',')" ];then IFS=',' read -r -a portArray <<< "$PortList" for port in ${portArray[@]};do conncetHostPortArray+=("$newIP:$port") done else conncetHostPortArray+=("$newIP:$PortList") fi done #單IP else newIP=$IPList if [ -n "$(echo $PortList | grep ',')" ];then IFS=',' read -r -a portArray <<< "$PortList" for port in ${portArray[@]};do conncetHostPortArray+=("$newIP:$port") done else conncetHostPortArray+=("$newIP:$PortList") fi fi } for hostPort in ${conncetHostPortArray[@]};do read -u6 { checkConnectToFile $hostPort echo >&6 } & done wait done < $connectIpPortFileName log_info "最終驗證檔案: $connectFileName" remove_file exec 6>&- exit 0 } remove_file() { rm -f ${connectFileName}.lock rm -f $ncErrFileName } main() { init $@ queue_init readFileToConnect } main $@
5. 指令碼所需配置示例
#IP與埠使用 | 進行分割,多IP或多埠使用,分割 192.168.1.38,39,40|443,80,111,1111 192.168.1.10|80,443,80 192.168.1.11,192.68.1.21|80
6. 執行方法
- 儲存指令碼命為 check_connect_status.sh
- 執行命令
bash check_connect_status.sh