如何写一个脚本自动重启服务

wen 实用脚本 1

本文目录导读:

如何写一个脚本自动重启服务

  1. 基础版 - 检查并重启服务 (Bash)
  2. 带重试机制的版本
  3. 监控进程并自动重启
  4. 使用 cron 定时检查
  5. 增强版 - 带日志和告警
  6. 使用 systemd 定时器(推荐方案)
  7. 使用方法

我来帮你写一个自动重启服务的脚本,提供几种不同的实现方案:

基础版 - 检查并重启服务 (Bash)

#!/bin/bash
# 服务名称
SERVICE_NAME="your-service-name"
# 检查服务是否运行
if ! systemctl is-active --quiet $SERVICE_NAME; then
    echo "$(date): $SERVICE_NAME 未运行,正在重启..."
    systemctl restart $SERVICE_NAME
    # 验证重启结果
    if systemctl is-active --quiet $SERVICE_NAME; then
        echo "$(date): $SERVICE_NAME 重启成功"
    else
        echo "$(date): $SERVICE_NAME 重启失败"
    fi
fi

带重试机制的版本

#!/bin/bash
SERVICE_NAME="your-service-name"
MAX_RETRIES=3
RETRY_INTERVAL=10  # 秒数
restart_service() {
    local retry_count=0
    while [ $retry_count -lt $MAX_RETRIES ]; do
        echo "$(date): 尝试重启 $SERVICE_NAME (第 $((retry_count+1)) 次)"
        systemctl restart $SERVICE_NAME
        # 等待服务启动
        sleep 5
        if systemctl is-active --quiet $SERVICE_NAME; then
            echo "$(date): $SERVICE_NAME 重启成功"
            return 0
        fi
        ((retry_count++))
        sleep $RETRY_INTERVAL
    done
    echo "$(date): $SERVICE_NAME 重启失败,已达最大重试次数"
    send_alert "服务重启失败: $SERVICE_NAME"
    return 1
}
# 检查并重启
if ! systemctl is-active --quiet $SERVICE_NAME; then
    restart_service
fi

监控进程并自动重启

#!/bin/bash
# 监控的进程名或命令
PROCESS_NAME="your-process-name"
PROCESS_CMD="/path/to/your/command"
LOG_FILE="/var/log/process_monitor.log"
restart_process() {
    echo "$(date): 启动进程 $PROCESS_NAME" >> $LOG_FILE
    # 杀死旧进程(如果存在)
    pkill -f $PROCESS_NAME 2>/dev/null
    # 后台启动进程
    nohup $PROCESS_CMD > /dev/null 2>&1 &
    # 等待进程启动
    sleep 2
    # 检查进程是否启动
    if pgrep -f $PROCESS_NAME > /dev/null; then
        echo "$(date): 进程 $PROCESS_NAME 启动成功" >> $LOG_FILE
        return 0
    else
        echo "$(date): 进程 $PROCESS_NAME 启动失败" >> $LOG_FILE
        return 1
    fi
}
# 主循环
while true; do
    if ! pgrep -f $PROCESS_NAME > /dev/null; then
        echo "$(date): 进程 $PROCESS_NAME 不存在,正在重启..." >> $LOG_FILE
        restart_process
        if [ $? -ne 0 ]; then
            echo "$(date): 重启失败,等待 30 秒后重试" >> $LOG_FILE
            sleep 30
            continue
        fi
    fi
    sleep 10
done

使用 cron 定时检查

#!/bin/bash
# 保存为 /usr/local/bin/service_monitor.sh
# 然后添加到 crontab: */5 * * * * /usr/local/bin/service_monitor.sh
SERVICE_NAME="your-service"
MAX_MEMORY=500  # MB,可选:内存限制
MAX_CPU=90      # 百分比,可选:CPU限制
restart_service() {
    echo "$(date): 开始重启服务 $SERVICE_NAME"
    systemctl restart $SERVICE_NAME
    echo "$(date): 服务 $SERVICE_NAME 已重启"
    logger "服务 $SERVICE_NAME 已自动重启"
}
# 1. 检查服务是否运行
if ! systemctl is-active --quiet $SERVICE_NAME; then
    restart_service
    exit 0
fi
# 2. 检查资源使用(可选)
PID=$(pgrep -f $SERVICE_NAME | head -1)
if [ ! -z "$PID" ]; then
    # 检查内存
    MEMORY=$(ps -o rss= -p $PID | awk '{print $1/1024}')
    if [ $(echo "$MEMORY > $MAX_MEMORY" | bc) -eq 1 ]; then
        echo "$(date): 内存使用超过限制 ($MEMORY MB)"
        restart_service
        exit 0
    fi
    # 检查CPU
    CPU=$(ps -o %cpu= -p $PID)
    if [ $(echo "$CPU > $MAX_CPU" | bc) -eq 1 ]; then
        echo "$(date): CPU使用超过限制 ($CPU%)"
        restart_service
        exit 0
    fi
fi

增强版 - 带日志和告警

#!/bin/bash
# 配置
SERVICE_NAME="your-service"
LOG_DIR="/var/log/service_auto_restart"
LOG_FILE="$LOG_DIR/restart.log"
ALERT_EMAIL="admin@example.com"
MAX_RESTARTS=5  # 每小时最大重启次数
RESTART_COUNT_FILE="/tmp/restart_count"
# 创建日志目录
mkdir -p $LOG_DIR
# 记录日志
log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S'): $1" >> $LOG_FILE
}
# 发送告警
send_alert() {
    local message="$1"
    echo "$message" | mail -s "服务重启告警: $SERVICE_NAME" $ALERT_EMAIL
    log "发送告警: $message"
}
# 检查重启频率
check_restart_rate() {
    local current_hour=$(date +%H)
    local current_count=0
    # 读取当前小时的重启次数
    if [ -f "$RESTART_COUNT_FILE" ]; then
        local saved_hour=$(cat $RESTART_COUNT_FILE | head -1)
        if [ "$saved_hour" == "$current_hour" ]; then
            current_count=$(cat $RESTART_COUNT_FILE | tail -1)
        else
            # 新的一小时,重置计数
            current_count=0
        fi
    fi
    if [ $current_count -ge $MAX_RESTARTS ]; then
        log "达到每小时最大重启次数 ($MAX_RESTARTS)"
        return 1
    fi
    # 更新计数
    echo "$current_hour" > $RESTART_COUNT_FILE
    echo $((current_count + 1)) >> $RESTART_COUNT_FILE
    return 0
}
# 重启服务
restart_service() {
    log "开始重启服务 $SERVICE_NAME"
    # 记录重启原因
    if [ ! -z "$1" ]; then
        log "重启原因: $1"
    fi
    # 执行重启
    systemctl restart $SERVICE_NAME
    local restart_status=$?
    sleep 5
    # 验证
    if systemctl is-active --quiet $SERVICE_NAME; then
        log "服务重启成功"
        # 检查重启频率
        if ! check_restart_rate; then
            send_alert "服务频繁重启,请检查: $SERVICE_NAME"
        fi
        return 0
    else
        log "服务重启失败"
        send_alert "服务重启失败: $SERVICE_NAME"
        return 1
    fi
}
# 主逻辑
main() {
    # 检查服务状态
    if ! systemctl is-active --quiet $SERVICE_NAME; then
        restart_service "服务未运行"
        exit $?
    fi
    # 检查是否僵死
    if systemctl status $SERVICE_NAME | grep -q "Active: activating"; then
        restart_service "服务卡在激活状态"
        exit $?
    fi
    log "服务运行正常"
}
main

使用 systemd 定时器(推荐方案)

创建 Timer 配置文件 /etc/systemd/system/service_monitor.timer

[Unit]
Description=Service Monitor Timer
Requires=service_monitor.service
[Timer]
OnCalendar=*:0/5
Persistent=true
[Install]
WantedBy=timers.target

创建服务文件 /etc/systemd/system/service_monitor.service

[Unit]
Description=Service Monitor
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/service_monitor.sh
StandardOutput=journal

启用定时器:

sudo systemctl enable service_monitor.timer
sudo systemctl start service_monitor.timer

使用方法

  1. 修改配置:将 your-service-name 替换为实际的服务名
  2. 添加执行权限
    chmod +x script.sh
  3. 设置定时任务
    crontab -e  # 添加每分钟检查
    * * * * * /path/to/script.sh

选择适合你场景的方案,建议先测试再部署到生产环境。

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