本文目录导读:

- 方案一:Supervisor(最推荐,PHP官方常用)
- 方案二:Systemd(系统级,适合开机自启)
- 方案三:Shell 循环 + nohup(极简临时方案)
- 方案四:Docker + Restart Policy(容器化场景)
- 方案五:PHP 内部自守护(适合单进程服务)
- 关键注意点
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_log 或 log_errors,否则悲剧了找不到原因 |
| 拉起频率限制 | Supervisor/Systemd 都有 restartsec 防止无限重启 |
| FPM 进程(如 Nginx+PHP-FPM) | 本身有 pm.max_children 和 pm.start_servers 自动管理,一般不推荐 supervisor 管 FPM,直接用自带机制 |
你具体是什么场景?
我见过很多:
- Laravel/ThinkPHP 队列 → 用 Supervisor 最合适
- WebSocket 长连接 → Supervisor 或 Systemd
- 定时任务(cron) → 用 Cron 本身 + 锁文件即可,不需要常驻
- TCP/UDP 服务 → 也用 Supervisor
告诉我你的具体业务,我可以给出更精准的配置。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播