自动重启崩溃程序的脚本

wen 实用脚本 4

本文目录导读:

自动重启崩溃程序的脚本

  1. 基础版 Shell 脚本
  2. systemd 方式(推荐)
  3. Python 监控脚本(功能更强大)
  4. Docker 方式(容器化)
  5. 使用 supervisor(适用于 Python 程序)
  6. 使用建议

我来提供一个自动重启崩溃程序的脚本,涵盖多种场景:

基础版 Shell 脚本

#!/bin/bash
# 程序名称
PROGRAM_NAME="your_program"
# 程序路径
PROGRAM_PATH="/path/to/your/program"
# 日志文件
LOG_FILE="/var/log/program_restart.log"
# 最大重启次数(可选)
MAX_RESTARTS=10
# 重启间隔(秒)
RESTART_INTERVAL=5
# 重启计数器
restart_count=0
# 日志函数
log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 检查程序是否运行
check_process() {
    if pgrep -f "$PROGRAM_NAME" > /dev/null; then
        return 0
    else
        return 1
    fi
}
# 主循环
while true; do
    if ! check_process; then
        restart_count=$((restart_count + 1))
        if [ $restart_count -gt $MAX_RESTARTS ]; then
            log "程序已重启超过 $MAX_RESTARTS 次,停止监控"
            exit 1
        fi
        log "程序已停止,正在重启 (第 $restart_count 次)..."
        # 启动程序(后台运行)
        $PROGRAM_PATH &
        log "程序已重新启动"
        sleep $RESTART_INTERVAL
    else
        restart_count=0  # 程序正常运行,重置计数器
        sleep 10  # 每10秒检查一次
    fi
done

systemd 方式(推荐)

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

[Unit]
Description=My Application Service
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/path/to/app
ExecStart=/path/to/your/program
Restart=always
RestartSec=5
StartLimitInterval=60
StartLimitBurst=5
# 可选:内存限制
MemoryMax=500M
# 可选:CPU限制
CPUQuota=50%
# 可选:超时设置
TimeoutStopSec=30
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target

使用命令:

# 启动服务
sudo systemctl start myapp
# 设置开机自启
sudo systemctl enable myapp
# 查看状态
sudo systemctl status myapp
# 查看日志
journalctl -u myapp -f

Python 监控脚本(功能更强大)

#!/usr/bin/env python3
import subprocess
import time
import logging
import os
import signal
import sys
from datetime import datetime
class ProcessMonitor:
    def __init__(self, cmd, max_restarts=10, restart_interval=5, log_file='process_monitor.log'):
        self.cmd = cmd
        self.max_restarts = max_restarts
        self.restart_interval = restart_interval
        self.restart_count = 0
        self.process = None
        # 配置日志
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler(log_file),
                logging.StreamHandler()
            ]
        )
        self.logger = logging.getLogger(__name__)
    def start_process(self):
        """启动进程"""
        try:
            self.logger.info(f"启动程序: {self.cmd}")
            self.process = subprocess.Popen(
                self.cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                universal_newlines=True
            )
            self.logger.info(f"程序启动成功,PID: {self.process.pid}")
            return True
        except Exception as e:
            self.logger.error(f"启动程序失败: {e}")
            return False
    def check_process(self):
        """检查进程状态"""
        if self.process is None:
            return False
        # 检查进程是否还在运行
        if self.process.poll() is None:
            return True
        return False
    def restart_process(self):
        """重启进程"""
        self.restart_count += 1
        if self.restart_count > self.max_restarts:
            self.logger.warning(f"重启次数超过限制 {self.max_restarts} 次,停止监控")
            return False
        self.logger.info(f"重启程序 (第 {self.restart_count} 次)...")
        time.sleep(self.restart_interval)
        return self.start_process()
    def monitor(self):
        """主监控循环"""
        self.logger.info("开始监控程序...")
        if not self.start_process():
            sys.exit(1)
        try:
            while True:
                if not self.check_process():
                    self.logger.warning("程序已停止运行")
                    if not self.restart_process():
                        break
                else:
                    # 程序正常运行,重置计数器
                    if self.restart_count > 0:
                        self.logger.info("程序运行正常,重置重启计数器")
                        self.restart_count = 0
                time.sleep(5)  # 每5秒检查一次
        except KeyboardInterrupt:
            self.logger.info("收到停止信号,正在退出...")
            if self.process:
                self.process.terminate()
                self.logger.info("程序已停止")
def main():
    # 配置
    command = "python3 your_program.py"  # 你的程序命令
    monitor = ProcessMonitor(
        cmd=command,
        max_restarts=5,
        restart_interval=5,
        log_file='monitor.log'
    )
    monitor.monitor()
if __name__ == "__main__":
    main()

Docker 方式(容器化)

创建 docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    restart: always
    restart_policy:
      condition: on-failure
      delay: 5s
      max_attempts: 3
      window: 120s
    environment:
      - NODE_ENV=production
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

使用 supervisor(适用于 Python 程序)

安装 supervisor:

sudo apt-get install supervisor

创建配置文件 /etc/supervisor/conf.d/myapp.conf

[program:myapp]
command=/usr/bin/python3 /path/to/your/program.py
directory=/path/to/app
autostart=true
autorestart=true
startsecs=10
startretries=3
stopasgroup=true
killasgroup=true
user=your_user
redirect_stderr=true
stdout_logfile=/var/log/myapp.out.log
stderr_logfile=/var/log/myapp.err.log
stdout_logfile_maxbytes=10MB
stderr_logfile_maxbytes=10MB
environment=ENVIRONMENT="production"

使用建议

  1. 生产环境:推荐使用 systemdsupervisor,它们更稳定可靠
  2. 测试环境:可以使用简单 Shell 脚本或 Python 脚本
  3. 容器环境:使用 Docker 的 restart 策略
  4. 关键程序:建议添加监控告警(如邮件、短信通知)

选择哪种方案取决于你的具体需求和环境,如果需要更多定制,请告诉我具体的应用场景!

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