运维脚本:网络连通性测试

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
}

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

 

posted @ 2024-11-29 16:16  小书童·阿杰  阅读(61)  评论(0编辑  收藏  举报