Очередь позволяет вынести медленную работу — отправку писем, генерацию отчётов, обработку загруженных файлов — из HTTP-запроса в фоновый процесс. И Laravel, и Symfony умеют класть задачи в очередь, но сам обработчик задач — это отдельный долгоживущий процесс PHP, за которым нужно следить. Именно для этого нужен Supervisor.
Зачем нужен отдельный процесс-воркер
Команда вроде php artisan queue:work в Laravel или
messenger:consume в Symfony запускается один раз и работает,
пока её не остановят или пока процесс не упадёт из-за необработанного
исключения. Без надзирателя такой процесс рано или поздно завершится, а
задачи будут копиться в очереди без единого обработчика. Настройка самого
Symfony на сервере разобрана в статье
про Symfony на VPS.
Supervisor — демон, который запускает указанные процессы, перезапускает их при падении и позволяет держать сразу несколько одинаковых воркеров для параллельной обработки очереди.
Установка и базовый конфиг
sudo apt install supervisor
sudo mkdir -p /etc/supervisor/conf.d
sudo nano /etc/supervisor/conf.d/laravel-worker.conf
Пример конфига для Laravel-очереди с несколькими воркерами:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
directory=/var/www/app
autostart=true
autorestart=true
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/www/app/storage/logs/worker.log
stopwaitsecs=3600
Ключевые параметры конфига
| Параметр | Значение | Зачем нужен |
|---|---|---|
| numprocs | 4 | число параллельных воркеров на очередь |
| autorestart | true | перезапуск при падении процесса |
| stopwaitsecs | 3600 | время на завершение текущей задачи перед kill |
| max-time / --time-limit | 3600 | плановый перезапуск воркера раз в час |
Плановый перезапуск воркера важен: PHP-процесс, который живёт часами, постепенно накапливает память из-за утечек в сторонних библиотеках. Раз в час Supervisor просто поднимает свежую копию процесса вместо старой.
Команды управления и применения конфига
supervisorctl reread— Supervisor видит новый или изменённый файл конфига вconf.d.supervisorctl update— применяет изменения: запускает новые программы, останавливает удалённые.supervisorctl restart laravel-worker:*— перезапускает все воркеры группы после деплоя нового кода.supervisorctl status— показывает состояние каждого воркера и время его последнего запуска.
Частые причины зависших и потерянных задач
После деплоя нового релиза старые воркеры продолжают работать со старым
кодом в памяти, пока их не перезапустят вручную через
supervisorctl restart — это стоит добавить в скрипт деплоя как
обязательный шаг. Ещё одна частая причина — воркер держит соединение с
базой данных, которое MySQL обрывает по таймауту простоя, и следующая
задача падает с ошибкой "MySQL server has gone away". Для CLI-запусков
воркеров полезно понимать разницу с обработкой запросов через FPM — она
описана в статье про PHP CLI и
FPM. Диагностировать падения проще всего по логам самого воркера и по
общему логу ошибок PHP — порядок разбора описан в статье
про разбор логов PHP.
Чек-лист настройки очередей на проде
- Задайте
--triesи--max-timeв команде воркера, чтобы зависшая задача не блокировала очередь навсегда. - Добавьте
supervisorctl restartв скрипт деплоя сразу после обновления кода на сервере. - Настройте отдельный лог для воркеров и мониторинг числа задач в очереди, чтобы заметить рост очереди раньше пользователей.