Черга дозволяє винести повільну роботу — надсилання листів, генерацію звітів, обробку завантажених файлів — з 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у скрипт деплою одразу після оновлення коду на сервері. - Налаштуйте окремий лог для воркерів і моніторинг кількості задач у черзі, щоб помітити зростання черги раніше за користувачів.