Laravel 如何配置 Supervisor 守护队列进程防止意外退出
核心结论:生产环境中 Supervisor 配置必须设置 stopwaitsecs=3600 和 startsecs=5,否则进程可能在完成任务前被强制终止或误判启动失败(2026 年 1 月 14 日实测数据)。
原因分析
Laravel 队列进程意外退出的主要原因有三点:第一,默认 QUEUE_CONNECTION=sync 驱动不会真正进入队列,导致任务积压在 pending 状态(2026 年 1 月 14 日资料确认);第二,Supervisor 未配置 startsecs=5 时,进程启动后 1 秒内无输出即被判定为启动失败,导致反复重启;第三,queue:work 进程未设置--max-jobs 参数时,长时间运行会引发内存泄漏,实测连续处理 1000+ 任务后内存占用可从 128MB 增至 512MB 以上。
解决方案
一、安装并验证 Supervisor 服务
Ubuntu/Debian 系统执行:sudo apt install supervisor -y,安装完成后运行 sudo systemctl status supervisor 确认状态为 active (running)(2025 年 7 月 15 日验证步骤)。CentOS/RHEL 系统需先执行 sudo yum install epel-release -y 再安装 supervisor。
二、创建 Supervisor 配置文件
在/etc/supervisor/conf.d/目录下创建 laravel-worker.conf,填入以下经生产验证的配置(2026 年 1 月 7 日发布):
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/your-app/artisan queue:work --queue=reports,default --sleep=3 --tries=3 --max-jobs=250 --max-time=3600
autostart=true
autorestart=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/supervisor/worker.log
stopwaitsecs=3600
killasgroup=true
stopasgroup=true
关键参数说明:--max-jobs=250 表示每处理 250 个任务后自动重启进程,防止内存泄漏;--max-time=3600 限制进程最长运行 3600 秒;stopwaitsecs=3600 确保停止时给足时间完成当前任务(2025 年 11 月 3 日资料强调此参数必要性)。
三、配置优雅重启策略
代码更新后需执行 php artisan queue:restart 触发优雅重启,该命令向 Laravel 队列系统写入时间戳信号,所有 queue:work 进程完成当前任务后检查信号并自动退出(Laravel 8+ 默认启用--daemon 模式)。验证信号是否生效:运行 php artisan tinker 后输入 Cache::get('laravel_queue_restart_signal'),返回时间戳即表示信号已写入(2026 年 4 月 11 日验证方法)。注意:若使用 database 驱动,需确保 cache 驱动非 array,否则信号无法跨进程共享,推荐使用 redis 或 file 缓存驱动。
四、重载配置并启动进程
修改配置后执行以下命令序列(2025 年 11 月 3 日标准流程):
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl status
确认 laravel-worker 状态为 RUNNING。若使用多队列,可为不同队列创建独立配置文件,如/etc/supervisor/conf.d/laravel-work.ini 中配置 [group:events] 组,numprocs=4 启动 4 个进程实例(2026 年 4 月 11 日多队列配置案例)。
五、RabbitMQ 队列优化配置(可选)
若使用 RabbitMQ 驱动,可采用以下高吞吐量配置(2025 年 6 月 20 日优化方案):
command=php /path/to/artisan queue:work rabbitmq --prefetch=50 --timeout=120 --backoff=300 --max-time=3600 --memory=256 --sleep-when-empty=0.1 --batch=100 --max-jobs=500
numprocs=16
其中--prefetch=50 控制每次预取消息数,--memory=256 限制内存使用 256MB,numprocs=16 启动 16 个并行进程。
注意事项
1. 队列卡在 pending 状态排查:执行 dispatch(new SendEmailJob()) 后,若 php artisan queue:work 无输出且数据库 jobs 表为空,说明未走数据库驱动;若 Redis 里有 queues:default 列表但进程启动后立刻退出,多半是 Redis 连接失败或权限问题(2026 年 1 月 14 日常见错误现象总结)。
2. 配置缓存问题:修改.env 中的 QUEUE_CONNECTION=redis 后,必须执行 php artisan config:clear,否则 Laravel 会缓存旧配置导致队列驱动不生效(2026 年 1 月 14 日强调)。
3. 日志路径必须用绝对路径:如/var/log/supervisor/laravel-queue.log,避免权限或路径解析问题(2026 年 1 月 14 日建议)。
4. 无 Supervisor 环境替代方案:在部分 Plesk 或共享主机无法部署 Supervisor 时,可通过系统 Cron 每分钟检查重启信号并主动终止旧进程,实现类优雅效果(截至 2026 年 4 月 11 日方案)。
5. 多服务器部署:多服务器环境可使用 Redis Pub/Sub 广播重启信号,确保所有节点同步重启(2026 年 4 月 11 日多服务器方案)。
参考来源
来源:Laravel 运维技术文档 - Laravel 配置队列进程优雅重启策略方法(2026 年 4 月 11 日)
来源:Laravel Supervisor 实战指南 - laravel supervisor 队列 worker 守护配置(2025 年 11 月 3 日)
来源:队列系统优化手册 - 如何为 Laravel 应用配置高效的队列系统 (Redis 与 Supervisor 实战)(2026 年 1 月 14 日)
来源:进程管理最佳实践 - Supervisor 使用教程:进程守护的最佳实践指南(2025 年 7 月 15 日)