PHP进程意外退出咋拉起

wen PHP项目 1

本文目录导读:

PHP进程意外退出咋拉起

  1. 方案一:Supervisor(最推荐,PHP官方常用)
  2. 方案二:Systemd(系统级,适合开机自启)
  3. 方案三:Shell 循环 + nohup(极简临时方案)
  4. 方案四:Docker + Restart Policy(容器化场景)
  5. 方案五:PHP 内部自守护(适合单进程服务)
  6. 关键注意点

PHP进程意外退出(如崩溃、OOM被系统杀掉等)是非常常见的问题,拉起(守护)进程有几种成熟方案,从简单到复杂,可以根据你的实际场景选择:


Supervisor(最推荐,PHP官方常用)

这是 PHP-FPM、队列进程(如 Laravel Queue Worker)、常驻脚本最主流的守护方案。

安装

# Ubuntu / Debian
apt-get install -y supervisor
# CentOS / RHEL
yum install -y supervisor

配置示例(守护一个PHP常驻脚本)

创建 /etc/supervisor/conf.d/my-worker.conf

[program:my_worker]
; 启动命令 - 注意使用绝对路径
command=php /var/www/html/worker.php
; 进程用户
user=www-data
; 自动启动
autostart=true
; 意外退出自动重启
autorestart=true
; 重启间隔时间(秒)
startsecs=3
startretries=3
; 日志
stdout_logfile=/var/log/my_worker.out.log
stderr_logfile=/var/log/my_worker.err.log
; 最大内存占用(超了会kill并重启,防止内存泄漏)
memory_limit=512MB

启动与常用命令

supervisorctl reread
supervisorctl update
supervisorctl start my_worker
supervisorctl status

优点:配置简单、支持多进程、有Web管理界面、内存限制、重启策略清晰。


Systemd(系统级,适合开机自启)

如果你的 PHP 进程是系统服务级别的,用 systemd 天然集成开机自启。

创建 Service 文件

/etc/systemd/system/php-worker.service

[Unit]
Description=PHP Worker Service
After=network.target
[Service]
; 工作目录
WorkingDirectory=/var/www/html
; 启动命令
ExecStart=/usr/bin/php /var/www/html/worker.php
; 崩溃自动重启
Restart=always
RestartSec=3
; 用户和组
User=www-data
Group=www-data
; 如果卡死,强制杀掉
TimeoutStopSec=10
; 内存限制(可选,触发 OOM 会重启)
MemoryMax=512M
[Install]
WantedBy=multi-user.target

启用和启动

systemctl daemon-reload
systemctl enable php-worker
systemctl start php-worker
# 查看状态和日志
systemctl status php-worker
journalctl -u php-worker -f

Shell 循环 + nohup(极简临时方案)

不推荐生产,但快速验证时很好用:

#!/bin/bash
while true; do
    php /var/www/html/worker.php
    # 退出后等2秒再重启
    sleep 2
done

后台运行:

nohup ./restart.sh > /dev/null 2>&1 &

Docker + Restart Policy(容器化场景)

如果进程跑在 Docker 里,直接依赖 Docker 的重启策略:

# docker-compose.yml 示例
services:
  php-worker:
    image: php:8.2-cli
    command: ["php", "/app/worker.php"]
    restart: always

这里 restart: always 表示:容器退出(无论退出码是什么)都会重启,除非显式 docker stop


PHP 内部自守护(适合单进程服务)

某些长驻进程(如 WebSocket、TCP服务)可以在脚本内部捕获异常并重启协程/worker。

<?php
while (true) {
    try {
        // 你的核心业务代码
        someLongRunningTask();
    } catch (\Throwable $e) {
        // 记录异常,稍后自动重试
        error_log("Worker crashed: " . $e->getMessage());
        sleep(5); // 防止频繁 crash
        continue;
    }
    // 正常退出(例如任务完成一次),继续循环
    usleep(100000);
}

这个只解决 PHP 代码异常导致的退出,解决不了 OOM Kill段错误


关键注意点

问题 注意事项
内存泄漏 常驻进程要定期 gc_collect_cycles(),并配合 memory_limit 触发重启
僵尸进程 若长时间不退出的子进程,手动 kill -9,但注意拉起策略需能应对 kill -9
日志排查 一定要开启 error_loglog_errors,否则悲剧了找不到原因
拉起频率限制 Supervisor/Systemd 都有 restartsec 防止无限重启
FPM 进程(如 Nginx+PHP-FPM) 本身有 pm.max_childrenpm.start_servers 自动管理,一般不推荐 supervisor 管 FPM,直接用自带机制

你具体是什么场景?

我见过很多:

  • Laravel/ThinkPHP 队列 → 用 Supervisor 最合适
  • WebSocket 长连接 → Supervisor 或 Systemd
  • 定时任务(cron) → 用 Cron 本身 + 锁文件即可,不需要常驻
  • TCP/UDP 服务 → 也用 Supervisor

告诉我你的具体业务,我可以给出更精准的配置。

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