- A+
所属分类:.NET技术
1. 背景介绍
在日常运维工作中,网络连通性是确保系统稳定性和高可用性的关键因素之一。通过测试网络连通性,运维人员可以快速诊断网络问题,判断系统与其他设备或服务的连接状态。这对于预防和处理网络故障至关重要。
本文将介绍如何编写和使用一个简单的运维脚本,来自动化测试服务器的网络连通性。
2. 目标描述
本文的目标是创建一个运维脚本,用于测试服务器之间的网络连接是否正常。该脚本能够:
- 检查与目标IP或域名的连通性。
- 提供网络连通性测试的结果(如是否连接成功,响应时间等)。
- 对不同的网络故障类型进行简单的错误提示,帮助快速定位问题。
3. 脚本设计思路
在测试网络连通性时,我们通常会使用以下工具:
- Nc 命令:用来测试网络连接性,检查目标主机是否可达。
- Traceroute 命令(可选):用于分析网络路由,帮助定位中断的节点。
脚本设计应简洁明了,能够通过参数传递目标IP或域名,并且输出直观的测试结果。
4. 脚本示例
#!/bin/bash # checkConnectStatus.sh # 批量测试网络连通性脚本 log_err() { printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: 33[31mERROR: 33[0m$@n" } log_info() { printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: 33[32mINFO: 33[0m$@n" } log_warning() { printf "[$(date +'%Y-%m-%dT%H:%M:%S')]: 33[33mWARNING: 33[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 } 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