Shell脚本如何实现存活探针

wen 实用脚本 19

本文目录导读:

Shell脚本如何实现存活探针

  1. 基础TCP端口探测
  2. HTTP健康检查探针
  3. 完整的探针函数
  4. 带日志的探针实现
  5. 自定义健康检查脚本
  6. 使用nc工具
  7. 使用建议

Shell脚本实现存活探针通常用于检测服务或主机是否正常运行,以下是几种常见的实现方式:

基础TCP端口探测

#!/bin/bash
# TCP端口存活探测
host="127.0.0.1"
port=80
# 使用/dev/tcp进行探测
if timeout 3 bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then
    echo "服务正常运行"
else
    echo "服务异常"
fi

HTTP健康检查探针

#!/bin/bash
url="http://example.com/health"
expected_code=200
# 使用curl进行HTTP健康检查
response=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 $url)
if [ "$response" == "$expected_code" ]; then
    echo "服务健康"
else
    echo "服务异常,HTTP状态码: $response"
fi

完整的探针函数

#!/bin/bash
# 探测函数
health_check() {
    local host=$1
    local port=$2
    local timeout=${3:-5}
    # TCP连接探测
    if timeout $timeout bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then
        return 0
    else
        return 1
    fi
}
# 连续探测(带重试机制)
retry_check() {
    local max_retries=$1
    local retry_interval=$2
    shift 2
    local hosts=("$@")
    for ((i=1; i<=max_retries; i++)); do
        for host in "${hosts[@]}"; do
            IFS=':' read -r addr port <<< "$host"
            if health_check "$addr" "$port"; then
                echo "探测成功: $host"
                return 0
            fi
        done
        echo "第${i}次重试..."
        sleep $retry_interval
    done
    return 1
}
# 使用示例
retry_check 3 2 "192.168.1.1:80" "192.168.1.2:3306"

带日志的探针实现

#!/bin/bash
log_file="/var/log/healthcheck.log"
alert_email="admin@example.com"
safe_exit() {
    echo "$(date): 脚本异常退出" >> $log_file
    exit 1
}
trap safe_exit ERR
# 日志函数
log_check() {
    local status=$1
    local message=$2
    echo "$(date): [$status] $message" >> $log_file
    # 异常时发送告警
    if [ "$status" == "FAIL" ]; then
        echo "服务异常: $message" | mail -s "服务告警" $alert_email
    fi
}
# 主探测逻辑
check_service() {
    local service_name=$1
    local check_command=$2
    if eval $check_command; then
        log_check "OK" "$service_name 运行正常"
        return 0
    else
        log_check "FAIL" "$service_name 检测失败"
        return 1
    fi
}
# 多个服务检测
check_service "Web服务器" "curl -s -f http://localhost:80/health"
check_service "数据库" "timeout 3 bash -c 'echo >/dev/tcp/localhost/3306' 2>/dev/null"
check_service "Redis" "redis-cli ping"

自定义健康检查脚本

#!/bin/bash
# 配置文件
CONFIG_FILE="/etc/healthcheck.conf"
# 读取配置
source_config() {
    if [ -f "$CONFIG_FILE" ]; then
        source "$CONFIG_FILE"
    else
        echo "配置文件不存在"
        exit 1
    fi
}
# 进程检测
check_process() {
    local process_name=$1
    if pgrep -x "$process_name" > /dev/null; then
        echo "进程 $process_name 运行中"
        return 0
    else
        echo "进程 $process_name 未运行"
        return 1
    fi
}
# 文件检测
check_file() {
    local file_path=$1
    local min_age=$2  # 最小文件修改时间(分钟)
    if [ -f "$file_path" ]; then
        local file_time=$(stat -c %Y "$file_path")
        local current_time=$(date +%s)
        local age_minutes=$(( (current_time - file_time) / 60 ))
        if [ $age_minutes -le $min_age ]; then
            echo "文件 $file_path 在最近${min_age}分钟内更新过"
            return 0
        else
            echo "文件 $file_path 已超过${min_age}分钟未更新"
            return 1
        fi
    else
        echo "文件 $file_path 不存在"
        return 1
    fi
}
# 资源检测
check_resources() {
    local cpu_threshold=90
    local mem_threshold=90
    local disk_threshold=90
    # CPU使用率
    cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
    echo "CPU使用率: ${cpu_usage}%"
    # 内存使用率
    mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
    echo "内存使用率: ${mem_usage}%"
    # 磁盘使用率
    disk_usage=$(df -h / | awk 'NR==2 {print $5}' | cut -d'%' -f1)
    echo "磁盘使用率: ${disk_usage}%"
    if (( $(echo "$cpu_usage > $cpu_threshold" | bc -l) )); then
        return 1
    fi
    return 0
}
# 主函数
main() {
    source_config
    echo "开始健康检查..."
    # 检查各项服务
    check_process "nginx" || exit 1
    check_file "/var/log/nginx/access.log" 5 || exit 1
    check_resources || exit 1
    echo "所有检查通过"
}
main "$@"

使用nc工具

#!/bin/bash
# 使用nc进行端口探测
nc_health_check() {
    local host=$1
    local port=$2
    if nc -z -w 5 $host $port 2>/dev/null; then
        echo "端口 $host:$port 通畅"
        return 0
    else
        echo "端口 $host:$port 不通"
        return 1
    fi
}
# 批量端口检测
ports=(
    "127.0.0.1:80"
    "127.0.0.1:443"
    "127.0.0.1:3306"
)
for target in "${ports[@]}"; do
    IFS=':' read -r host port <<< "$target"
    nc_health_check "$host" "$port"
done

使用建议

  1. 超时设置:始终设置超时避免脚本挂起
  2. 重试机制:网络波动时建议实现重试
  3. 日志记录:记录检查结果便于排查
  4. 告警通知:异常时及时通知运维人员
  5. 资源隔离:避免探针消耗过多系统资源

选择哪种方式取决于你的具体需求场景,对于简单的端口检测,使用/dev/tcp最方便;对于HTTP服务,建议使用curl工具。

抱歉,评论功能暂时关闭!