You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Bash脚本通过Cron重复重启Nginx服务?

解决Cron脚本重复重启Nginx的问题

问题背景

我用wget检查URL返回错误,当错误码为5(SSL错误)时记录日志并重启Nginx,但脚本通过Cron每分钟执行一次,现在遇到的问题是:服务重启后如果错误仍存在,脚本会每分钟重复执行重启操作,需要避免这种情况。原脚本如下:

#!/bin/bash

URL='http://some-url-here/'
LOG='/var/log/nginx/health.log'

wget -q $URL
if [ $? = 5 ] ; then
echo "$(date). SSL Error." > $LOG
sudo service nginx restart
exit
fi

优雅实现方案

方案1:使用锁文件控制重启触发

核心思路是用一个锁文件标记“已执行过重启”,只有当锁文件不存在时才执行重启操作;当服务恢复正常时,删除锁文件,确保下次出错能正常触发重启。

修改后的脚本:

#!/bin/bash

URL='http://some-url-here/'
LOG='/var/log/nginx/health.log'
LOCK_FILE='/var/run/nginx_ssl_restart.lock'

# 执行URL检查
wget -q "$URL"
EXIT_CODE=$?

if [ $EXIT_CODE -eq 5 ]; then
    # 检查锁文件是否存在,不存在则执行重启
    if [ ! -f "$LOCK_FILE" ]; then
        echo "$(date). SSL Error detected, restarting Nginx..." >> "$LOG"
        sudo service nginx restart
        # 创建锁文件
        touch "$LOCK_FILE"
    else
        echo "$(date). SSL Error still exists, skip restart (lock file present)" >> "$LOG"
    fi
else
    # 错误恢复,删除锁文件
    if [ -f "$LOCK_FILE" ]; then
        echo "$(date). Service restored, removing lock file" >> "$LOG"
        rm "$LOCK_FILE"
    fi
fi

方案2:基于时间冷却的重启控制

如果希望在一段时间内(比如5分钟)只执行一次重启,可以记录上次重启的时间,每次检测到错误时对比当前时间,超过冷却时间才重启。

修改后的脚本:

#!/bin/bash

URL='http://some-url-here/'
LOG='/var/log/nginx/health.log'
LAST_RESTART_FILE='/var/run/nginx_last_restart_time'
COOL_DOWN=300  # 冷却时间,单位秒(5分钟)

# 执行URL检查
wget -q "$URL"
EXIT_CODE=$?

if [ $EXIT_CODE -eq 5 ]; then
    CURRENT_TIME=$(date +%s)
    # 检查上次重启时间文件是否存在
    if [ -f "$LAST_RESTART_FILE" ]; then
        LAST_RESTART=$(cat "$LAST_RESTART_FILE")
        TIME_DIFF=$((CURRENT_TIME - LAST_RESTART))
        # 如果时间差小于冷却时间,跳过重启
        if [ $TIME_DIFF -lt $COOL_DOWN ]; then
            echo "$(date). SSL Error exists, but within cool down period, skip restart" >> "$LOG"
            exit 0
        fi
    fi
    # 执行重启并记录时间
    echo "$(date). SSL Error detected, restarting Nginx..." >> "$LOG"
    sudo service nginx restart
    echo "$CURRENT_TIME" > "$LAST_RESTART_FILE"
else
    # 错误恢复,删除时间记录文件(可选)
    if [ -f "$LAST_RESTART_FILE" ]; then
        rm "$LAST_RESTART_FILE"
    fi
fi

补充说明

  • 锁文件方案更直观,适合“错误未恢复时不重复重启”的核心需求;
  • 时间冷却方案适合允许在固定间隔后重试重启的场景;
  • 注意给锁文件/时间记录文件设置合适的权限,确保脚本具备读写权限;
  • 日志输出建议用>>追加而非>覆盖,保留完整的历史排查记录。

内容的提问来源于stack exchange,提问作者shy147

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:35:36