监控进程并重启的脚本怎么写

wen 实用脚本 1

从入门到生产级实战指南

目录导读

  1. 为什么需要进程监控脚本 —— 守护进程的核心价值
  2. 基础版:Shell 脚本实现进程守护 —— 5 行代码搞定
  3. 进阶版:Python 脚本带日志与告警 —— 企业级必备
  4. 常用技巧与陷阱规避 —— 避免僵尸进程、误判与死循环
  5. 高频问答(FAQ) —— 解决你最常见的困惑

为什么需要进程监控脚本

在服务器运维中,进程崩溃或假死是家常便饭,无论是 Node.js 应用、Java 服务还是数据库,一旦进程意外退出,就会导致服务不可用,手动重启不仅效率低,且无法做到 7×24 小时响应。监控进程并自动重启的脚本成为运维工程师的必备技能,它不仅能减少人工干预,还能在故障发生时快速恢复,是保障系统高可用性的第一道防线。

监控进程并重启的脚本怎么写

基础版:Shell 脚本实现进程守护

最简单的方式是使用 while 循环 + pgrep 检查进程是否存在,以下脚本适用于大多数 Linux 环境:

#!/bin/bash
PROCESS_NAME="myapp"  # 替换为你的进程名
while true; do
    if ! pgrep -f "$PROCESS_NAME" > /dev/null; then
        echo "$(date) - $PROCESS_NAME 未运行,正在重启..." >> /var/log/process_monitor.log
        nohup /path/to/your/app > /dev/null 2>&1 &
    fi
    sleep 10  # 每10秒检查一次
done

工作原理pgrep 查找进程,如果找不到( 取反),则执行启动命令。nohup 保证应用在后台运行且不受终端关闭影响,这个脚本虽简单,但已具备基本监控能力。

进阶版:Python 脚本带日志与告警

生产环境中,仅有重启还不够,我们往往需要记录日志发送告警,并避免重复启动,以下是一个 Python 版本,更适合复杂需求:

import subprocess
import time
import logging
import smtplib
from email.mime.text import MIMEText
logging.basicConfig(filename='/var/log/my_monitor.log', level=logging.INFO,
                    format='%(asctime)s - %(levelname)s - %(message)s')
def send_alert(process_name):
    msg = MIMEText(f"进程 {process_name} 已崩溃,系统已自动重启。")
    msg['Subject'] = f"[告警] {process_name} 重启通知"
    msg['From'] = "monitor@example.com"
    msg['To'] = "ops@example.com"
    # 此处省略SMTP连接代码,可按需配置
def is_running(pid_file):
    try:
        with open(pid_file, 'r') as f:
            pid = int(f.read().strip())
        return pid, subprocess.run(['kill', '-0', str(pid)], capture_output=True).returncode == 0
    except (FileNotFoundError, ValueError):
        return None, False
def start_process(cmd, pid_file):
    proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    with open(pid_file, 'w') as f:
        f.write(str(proc.pid))
    return proc.pid
if __name__ == '__main__':
    CMD = "python /opt/myapp/app.py"  # 你的启动命令
    PID_FILE = "/tmp/myapp.pid"
    while True:
        pid, running = is_running(PID_FILE)
        if not running:
            logging.warning("进程未运行,尝试重启...")
            new_pid = start_process(CMD, PID_FILE)
            logging.info(f"已重启,新PID: {new_pid}")
            send_alert("myapp")  # 可选
        time.sleep(15)

亮点:通过 PID 文件精准判断,避免误杀其他同名进程;集成了日志和邮件告警;使用 kill -0 检查进程是否存活(不发送信号,仅检测存在性)。

常用技巧与陷阱规避

  • 避免死循环误判:若应用启动需要较长时间,可在启动后加 sleep 5 再进入下一次检查,防止因启动延迟导致重复拉起。
  • 防止僵尸进程:使用 double-forksetsid 技术,确保子进程不被父进程退出影响。
  • 资源占用限制:可结合 ulimitsystemdMemoryMax 控制异常内存增长。
  • 更现代的选择:生产环境推荐使用 systemd serviceSupervisor,它们内置自动重启及故障转移策略,脚本适合轻量级或临时任务。

高频问答(FAQ)

Q1: 脚本本身崩溃了怎么办? A: 可将脚本设置为 cron 任务,每分钟执行一次,并在脚本内做单实例锁(如 flock 命令),防止多个副本同时运行。

Q2: 如何让脚本开机自启? A: 将启动命令写入 /etc/rc.local,或编辑 /etc/systemd/system/monitor.service 创建守护服务。

Q3: 进程被 kill -9 杀掉后,kill -0 能检测到吗? A: 可以。kill -0 检查的是 PID 是否存在,僵尸进程会返回成功,因此建议结合 ps -o stat= 查看进程状态是否为 Z

Q4: 能否用 Docker 实现类似效果? A: 可以,Docker 自带 --restart=always 参数,但注意容器内进程监控与宿主机维度不同,且重启策略不含健康检查,复杂场景可结合 docker-compose + healthcheck


延伸建议:若你管理的服务较多,推荐使用 Supervisor 的进程组管理功能,或 Kubernetes 中的 livenessProbe(探针),脚本方案更适合作为轻量化兜底,两者结合能构建更健壮的监控体系。

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