脚本如何检测服务是否正常

wen 实用脚本 2

本文目录导读:

脚本如何检测服务是否正常

  1. 端口检测(最基础)
  2. HTTP/HTTPS 健康检查(Web服务)
  3. TCP 连接 + 发送简单协议数据
  4. 进程与Systemd服务检测(本地进程)
  5. 按层检查的综合脚本
  6. 使用现成工具
  7. 关键要点

检测服务是否正常通常涉及网络连接、端口可用性、HTTP响应状态或自定义健康检查,以下是几种常见脚本检测方式,涵盖不同层级与语言:

端口检测(最基础)

检查目标服务的端口是否处于监听状态。

Bash

#!/bin/bash
host="192.168.1.100"
port=8080
# 使用nc或timeout+bash /dev/tcp
if timeout 3 bash -c "echo >/dev/tcp/$host/$port" 2>/dev/null; then
    echo "Service on $host:$port is UP"
else
    echo "Service on $host:$port is DOWN"
fi

PowerShell

$hostname = "192.168.1.100"
$port = 8080
$tcp = New-Object System.Net.Sockets.TcpClient
try {
    $tcp.Connect($hostname, $port)
    Write-Host "Service on $hostname:$port is UP"
} catch {
    Write-Host "Service on $hostname:$port is DOWN"
} finally {
    $tcp.Dispose()
}

HTTP/HTTPS 健康检查(Web服务)

检测HTTP状态码或响应内容是否正常。

Python

import requests
import sys
url = "http://192.168.1.100:8080/health"
timeout = 5
try:
    response = requests.get(url, timeout=timeout)
    # 更严格的检查:判断状态码是否为200-399区间
    if 200 <= response.status_code < 400:
        print(f"Service OK (Status: {response.status_code})")
        sys.exit(0)
    else:
        print(f"Service UNHEALTHY (Status: {response.status_code})")
        sys.exit(1)
except requests.exceptions.RequestException as e:
    print(f"Service DOWN or unreachable: {e}")
    sys.exit(1)

Bash (curl)

#!/bin/bash
url="http://192.168.1.100:8080/health"
expected_status="200"
http_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 10 "$url")
if [ "$http_code" = "$expected_status" ]; then
    echo "Health check PASSED (HTTP $http_code)"
    exit 0
else
    echo "Health check FAILED (HTTP $http_code)"
    exit 1
fi

TCP 连接 + 发送简单协议数据

对于自定义TCP服务(如Redis、Memcached、MQ),可以发一个ping命令检测。

Bash (Redis示例)

#!/bin/bash
host="127.0.0.1"
port=6379
# 发送PING命令并检查回复是否包含+PONG
response=$(echo -e "PING\r\n" | timeout 3 nc "$host" "$port" 2>/dev/null)
if [[ "$response" == *"+PONG"* ]]; then
    echo "Redis is UP"
else
    echo "Redis is DOWN"
fi

Python (通用TCP协议测试)

import socket
def check_service(host, port, send_data, expected_response, timeout=3):
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((host, port))
        sock.send(send_data.encode() if isinstance(send_data, str) else send_data)
        response = sock.recv(1024)
        sock.close()
        return expected_response in response.decode()
    except Exception as e:
        return False
# 检测MySQL: 发送握手包开始,检查是否返回服务器版本字符串
if check_service("127.0.0.1", 3306, b"\x00", "mysql_native_password"):
    print("MySQL is UP")
else:
    print("MySQL is DOWN")

进程与Systemd服务检测(本地进程)

检查服务进程是否存活或systemd服务状态。

Bash

# 通过进程名检测
if pgrep -x "nginx" > /dev/null 2>&1; then
    echo "nginx process is running"
else
    echo "nginx process is NOT running"
fi
# 通过systemd(适用于已注册的服务)
if systemctl is-active --quiet nginx; then
    echo "nginx service is active"
else
    echo "nginx service is inactive or failed"
fi

Python

import subprocess
# 使用pgrep
result = subprocess.run(["pgrep", "-x", "nginx"], capture_output=True)
if result.returncode == 0:
    print("nginx process is running")
else:
    print("nginx process is NOT running")

按层检查的综合脚本

组合端口、HTTP、应用逻辑检测:

#!/usr/bin/env python3
import socket
import requests
import sys
def check_port(host, port, timeout=3):
    """TCP端口检测"""
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(timeout)
        sock.connect((host, port))
        sock.close()
        return True
    except:
        return False
def check_http(host, port, path="/health"):
    """HTTP健康端点检测"""
    url = f"http://{host}:{port}{path}"
    try:
        r = requests.get(url, timeout=5)
        return r.ok or (200 <= r.status_code < 400)
    except:
        return False
def main():
    host = sys.argv[1] if len(sys.argv) > 1 else "127.0.0.1"
    ports = [80, 8080, 3306, 6379]
    for port in ports:
        port_up = check_port(host, port)
        print(f"Port {port}: {'UP' if port_up else 'DOWN'}")
        # 对常见端口进行HTTP检测
        if port_up and port in [80, 8080, 3000]:
            http_up = check_http(host, port)
            print(f"  HTTP health: {'UP' if http_up else 'DOWN'}")
if __name__ == "__main__":
    main()

使用现成工具

  • curlcurl -f http://host:port/health 如果状态码>=400则返回异常退出码
  • wgetwget --spider -q http://host:port/health
  • nmapnmap -p 80 host -oG - | grep 80/open
  • nc (netcat)nc -zv host port
  • tcpingtcping host port

关键要点

  1. 超时设置:避免检测被卡住,永远设置连接超时(≤5秒)
  2. 重试机制:单次失败可能是网络抖动,建议重试2-3次
  3. 应用层检测 > 端口检测:端口通不代表服务正常响应(可能进程卡死)
  4. 安全考虑:健康检查端点最好禁止修改或写入操作,只做只读检查
  5. 日志记录:失败时记录详细错误以便排查

根据你的服务类型(Web、数据库、自定义TCP、消息队列)选择最合适的检测方式,通常推荐组合端口+应用层(HTTP/协议ping)两类检测。

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