脚本如何检测服务是否存活

wen 实用脚本 1

本文目录导读:

脚本如何检测服务是否存活

  1. 基于TCP端口检测(通用性最强)
  2. 基于HTTP/HTTPS检测(Web服务)
  3. 基于进程检测(本地服务)
  4. 基于systemd服务检测
  5. 综合检测脚本(生产级)
  6. 特定数据库检测
  7. 使用工具检测
  8. 最佳实践建议

检测服务是否存活(健康检查)有多种脚本实现方式,具体取决于服务类型和网络环境,以下是几种常见方法:

基于TCP端口检测(通用性最强)

Shell脚本

#!/bin/bash
HOST="127.0.0.1"
PORT=8080
TIMEOUT=5
# 使用nc(netcat)检测
nc -z -w $TIMEOUT $HOST $PORT > /dev/null 2>&1
if [ $? -eq 0 ]; then
    echo "Service on $HOST:$PORT is UP"
    exit 0
else
    echo "Service on $HOST:$PORT is DOWN"
    exit 1
fi

使用/dev/tcp(bash内置)

#!/bin/bash
HOST="127.0.0.1"
PORT=8080
if timeout 5 bash -c "echo >/dev/tcp/$HOST/$PORT" 2>/dev/null; then
    echo "Service is UP"
    exit 0
else
    echo "Service is DOWN"
    exit 1
fi

基于HTTP/HTTPS检测(Web服务)

Shell脚本

#!/bin/bash
URL="http://127.0.0.1:8080/health"
TIMEOUT=10
# 使用curl检测
if curl -s -o /dev/null -w "%{http_code}" --connect-timeout $TIMEOUT $URL | grep -q "200\|301\|302"; then
    echo "HTTP service is UP"
    exit 0
else
    echo "HTTP service is DOWN"
    exit 1
fi
# 或者检查返回内容包含特定字符串
if curl -s --connect-timeout $TIMEOUT $URL | grep -q "healthy"; then
    echo "Service is healthy"
    exit 0
fi

Python脚本

#!/usr/bin/env python3
import requests
import sys
url = "http://127.0.0.1:8080/health"
try:
    response = requests.get(url, timeout=10)
    if response.status_code == 200 and "healthy" in response.text:
        print("Service is UP")
        sys.exit(0)
    else:
        print(f"Service returned status {response.status_code}")
        sys.exit(1)
except Exception as e:
    print(f"Service is DOWN: {e}")
    sys.exit(1)

基于进程检测(本地服务)

Shell脚本

#!/bin/bash
PROCESS_NAME="nginx"
# 检查进程是否存在
if pgrep -x "$PROCESS_NAME" > /dev/null; then
    echo "Process $PROCESS_NAME is running"
    exit 0
else
    echo "Process $PROCESS_NAME is not running"
    exit 1
fi
# 或者使用ps命令
if ps aux | grep -v grep | grep "$PROCESS_NAME" > /dev/null; then
    echo "Process found"
fi

基于systemd服务检测

#!/bin/bash
SERVICE_NAME="nginx.service"
if systemctl is-active --quiet "$SERVICE_NAME"; then
    echo "Service $SERVICE_NAME is active"
    exit 0
else
    echo "Service $SERVICE_NAME is inactive"
    exit 1
fi
# 查看详细状态
systemctl status "$SERVICE_NAME" --no-pager

综合检测脚本(生产级)

#!/bin/bash
SERVICE_NAME="myapp"
HOST="127.0.0.1"
PORT=8080
HEALTH_URL="http://$HOST:$PORT/health"
TIMEOUT=10
RETRY_COUNT=3
RETRY_INTERVAL=2
check_tcp() {
    nc -z -w $TIMEOUT $HOST $PORT > /dev/null 2>&1
}
check_http() {
    curl -s -o /dev/null -w "%{http_code}" --connect-timeout $TIMEOUT $HEALTH_URL | grep -q "200"
}
check_process() {
    pgrep -x "$SERVICE_NAME" > /dev/null 2>&1
}
main() {
    local retries=$RETRY_COUNT
    while [ $retries -gt 0 ]; do
        if check_tcp && check_http; then
            echo "[$(date)] $SERVICE_NAME is healthy"
            return 0
        fi
        retries=$((retries - 1))
        if [ $retries -gt 0 ]; then
            echo "[$(date)] Health check failed, retrying in ${RETRY_INTERVAL}s..."
            sleep $RETRY_INTERVAL
        fi
    done
    echo "[$(date)] $SERVICE_NAME is DOWN after $RETRY_COUNT retries"
    return 1
}
main "$@"

特定数据库检测

# MySQL检测
mysqladmin ping -h localhost -u root -p'password' > /dev/null 2>&1
# PostgreSQL检测
pg_isready -h localhost -p 5432 > /dev/null 2>&1
# Redis检测
redis-cli -h localhost -p 6379 ping > /dev/null 2>&1
# MongoDB检测
mongo --host localhost --port 27017 --eval "db.adminCommand('ping')" > /dev/null 2>&1

使用工具检测

使用systemctl(systemd系统)

systemctl is-active myservice.service

使用docker(容器化服务)

# 检查容器状态
docker inspect -f '{{.State.Status}}' container_name
# 或使用docker ps
docker ps --filter "status=running" --filter "name=container_name" -q

最佳实践建议

  1. 分层检测

    • 第一层:进程是否存在
    • 第二层:端口是否监听
    • 第三层:HTTP接口是否响应
    • 第四层:业务逻辑是否正常
  2. 超时设置:避免长时间阻塞

  3. 重试机制:防止偶发网络波动误判

  4. 日志记录:记录健康检查结果用于排查

  5. 告警集成:服务异常时自动告警

选择哪种检测方式取决于:

  • 服务类型(Web/API/数据库等)
  • 部署环境(容器/裸机/云服务)
  • 可用工具(netcat/curl/systemctl等)

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