本文目录导读:

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
使用建议
- 超时设置:始终设置超时避免脚本挂起
- 重试机制:网络波动时建议实现重试
- 日志记录:记录检查结果便于排查
- 告警通知:异常时及时通知运维人员
- 资源隔离:避免探针消耗过多系统资源
选择哪种方式取决于你的具体需求场景,对于简单的端口检测,使用/dev/tcp最方便;对于HTTP服务,建议使用curl工具。