脚本怎样实现进程自动重启

wen 实用脚本 25

本文目录导读:

脚本怎样实现进程自动重启

  1. 方案一:使用 while 循环 + 检查进程(纯 Shell 脚本,通用性强)
  2. 方案二:针对特定端口/URL 的健康检查(适合 Web 服务)
  3. 方案三:使用 crontab(定时检查,最低资源占用)
  4. 方案四:最推荐——使用 systemd 的自动重启功能(Linux 服务级)
  5. 选择建议
  6. 重要注意事项

实现进程自动重启的脚本,最常用的方法是通过循环检测进程状态,或者利用系统服务管理工具(如 systemd、Supervisor)来实现。

以下我为你提供 4 种常见的脚本实现方案,按推荐程度排序:

使用 while 循环 + 检查进程(纯 Shell 脚本,通用性强)

这种方式适合在容器内或简单的后台任务中使用。

原理:脚本会持续检查指定进程名称是否在运行,如果不在,就启动它。

#!/bin/bash
# 配置区
PROCESS_NAME="nginx"  # 你要监控的进程名
COMMAND="/usr/sbin/nginx"  # 启动该进程的命令(最好使用绝对路径)
CHECK_INTERVAL=10  # 检查间隔(秒)
# 主循环
while true; do
    # 检查进程是否存在(-x 表示精确匹配进程名,-c 统计数量)
    count=$(pgrep -x -c "$PROCESS_NAME")
    if [ "$count" -eq 0 ]; then
        echo "[$(date)] 检测到进程 $PROCESS_NAME 未运行,正在启动..."
        # 执行启动命令(如果需要后台运行,加上 &)
        $COMMAND &
        # 可选:等待几秒确认启动成功
        sleep 2
        if pgrep -x "$PROCESS_NAME" > /dev/null; then
            echo "[$(date)] 进程 $PROCESS_NAME 重启成功"
        else
            echo "[$(date)] 进程 $PROCESS_NAME 启动失败,请检查错误日志"
        fi
    fi
    sleep $CHECK_INTERVAL
done

如何运行

# 保存为 auto_restart.sh
chmod +x auto_restart.sh
# 后台运行(注意:关闭终端后需用 nohup 或 screen)
./auto_restart.sh &
# 更稳妥的方式使用 nohup 保持后台运行
nohup ./auto_restart.sh > restart.log 2>&1 &

针对特定端口/URL 的健康检查(适合 Web 服务)

如果进程运行了但卡死(听不到端口),上面基于进程名的方法可能误判,下面这个脚本会检测端口或 HTTP 响应。

#!/bin/bash
# 配置区
MONITOR_URL="http://localhost:8080/health"  # 健康检查 URL
RESTART_COMMAND="systemctl restart myapp"   # 重启命令
CHECK_INTERVAL=15                           # 检查间隔(秒)
# 如果检查失败次数累计达到阈值,才执行重启,防止误判
FAILURE_THRESHOLD=3
failure_count=0
while true; do
    # 使用 curl 检查服务健康状态
    # -f 表示失败时返回错误码,-s 静默,-o 忽略输出
    if curl -f -s -o /dev/null "$MONITOR_URL"; then
        # 健康检查成功
        if [ $failure_count -gt 0 ]; then
            echo "[$(date)] 服务恢复正常,重置失败计数"
        fi
        failure_count=0
    else
        # 健康检查失败
        ((failure_count++))
        echo "[$(date)] 健康检查失败 (第 $failure_count 次)"
        if [ $failure_count -ge $FAILURE_THRESHOLD ]; then
            echo "[$(date)] 连续失败 $FAILURE_THRESHOLD 次,执行重启..."
            $RESTART_COMMAND
            failure_count=0  # 重启后重置
            sleep 10        # 给系统一点时间恢复
        fi
    fi
    sleep $CHECK_INTERVAL
done

使用 crontab(定时检查,最低资源占用)

如果你不想让一个脚本一直跑(占用一个进程),可以用 cron 定时每分钟检查一次。

脚本片段 (/usr/local/bin/check_myapp.sh):

#!/bin/bash
PROCESS_NAME="myapp"
if ! pgrep -x "$PROCESS_NAME" > /dev/null; then
    echo "[$(date)] 进程 $PROCESS_NAME 已退出,cron 触发重启" >> /var/log/restart.log
    /usr/local/bin/start_myapp.sh
fi

设置 crontab(编辑:crontab -e):

# 每分钟执行一次检查
* * * * * /usr/local/bin/check_myapp.sh

最推荐——使用 systemd 的自动重启功能(Linux 服务级)

如果你的进程是系统服务,不要自己写脚本,直接用 systemd 是最稳定、最专业的方式。

示例 Service 文件 (/etc/systemd/system/myapp.service):

[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp_binary
Restart=always          # 关键:总是自动重启
RestartSec=5            # 重启前等待 5 秒
StartLimitInterval=0    # 不限制重启次数
[Install]
WantedBy=multi-user.target

使用

# 重新加载 systemd
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start myapp
# 启用开机自启
sudo systemctl enable myapp
# 查看状态(会显示重启次数)
sudo systemctl status myapp

选择建议

场景 推荐方案
你的进程是 Linux 标准服务 方案四(systemd) - 最专业,日志/资源管理都好
在 Docker 容器内运行 方案一(while 循环) 或 Docker 自带的 restart: always
只想临时用一下,不想改系统配置 方案一 或 方案三(crontab)
需要检测服务是否真正可用(能返回数据) 方案二(健康检查)
需要监控多个进程 可以用 Supervisor(比脚本更强大)

重要注意事项

  1. 避免无限重启:建议在脚本中加入重启次数计数,1 分钟内重启超过 5 次就停止,避免服务“死亡循环”。
  2. 日志输出:在脚本中加 echo [$(date)],方便排查问题。
  3. 权限问题:如果启动命令需要 sudo,记得配置 NOPASSWD 或在脚本中合理使用。
  4. 进程名冲突pgrep -x-x 参数表示精确匹配,避免误杀或误判同名字的其他进程。

如果你能告诉我你具体是用来监控什么进程(Java 应用、Node.js、数据库、Python 脚本),我可以帮你调整出最合适的脚本变体。

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