Новинка Виртуальный VDS сервер в Финляндии от 390р
Выберите продукт

Очереди и фоновые воркеры на VDS: Supervisor vs systemd, перезапуски и логи

Разбираем, как запускать очереди и фоновые воркеры на VDS: что выбрать — Supervisor или systemd, как настроить устойчивые рестарты без простоя, сколько поднимать процессов и где хранить логи. Приводим готовые конфиги для Laravel и PHP workers.
Очереди и фоновые воркеры на VDS: Supervisor vs systemd, перезапуски и логи

Очереди и фоновые воркеры — опора современной веб-архитектуры. Они разгружают приложение от тяжелых задач: отправка почты и push-уведомлений, генерация медиаконтента, интеграции, вебхуки, перерасчет кеша. На VDS мы сами решаем, кто будет следить за этими процессами, как их запускать, перезапускать и где хранить логи. На практике почти всегда выбор упирается в два варианта — Supervisor или systemd. Ниже — плюсы, минусы и готовые заготовки под php workers и laravel queue.

Зачем отдельные воркеры и очереди на VDS

HTTP-запросы должны быть быстрыми и предсказуемыми. Все, что может жить в фоне, уезжает в queues. Воркеры забирают задания из брокера (БД, Redis, AMQP) и выполняют их, не влияя на задержки веб-части. Это упрощает масштабирование: мы регулируем количество воркеров, приоритеты очередей, лимиты CPU и памяти независимо от фронтового трафика.

На VDS именно вы отвечаете за жизненный цикл процессов: автозапуск при старте, контроль падений, ограничения ресурсов, перезапуск при деплое (restart), хранение и ротация logs. Поэтому важно выбрать удобный механизм присмотра за воркерами и один раз аккуратно оформить базовый шаблон.

Supervisor vs systemd: что выбрать

Оба инструмента умеют запускать демоны, перезапускать их при сбое, собирать логи и управлять группами процессов. Разница — в культурном слое, интеграции с системой и возможностях тонкой настройки.

Когда Supervisor удобнее

Supervisor — классический процесс-менеджер на питоне, простой и понятный. Его любят за быстрый старт и удобные команды состояния. Он особенно привычен PHP-разработчикам благодаря множеству готовых примеров для laravel queue. Конфигурации компактны, просто копируются между серверами, легко собирать «группы» процессов (program/group) и держать по нескольку воркеров на очередь. Логи — отдельными файлами, с ротацией по размеру и бэкапами.

Минусы: дополнительная зависимость, отдельный демон, отдельная система логирования, меньше интеграции с лимитами ядра, cgroups и безопасностью. Некоторые корпоративные политики предпочитают чистый systemd без сторонних демонов.

Когда systemd логичнее

systemd — нативный для современных дистрибутивов. Он управляет автозапуском, зависимостями, лимитами CPU/IO/Memory, cgroups, изоляцией, журналом событий. Ядро и дистрибутив «знают» о ваших сервисах: их видно в systemctl, логи в journalctl, ресурсы регулируются без костылей. Перезапуск при деплое оформляется через ExecReload, а тонкая песочница и юнит-настройки помогают безопасности.

Из нюансов: конфигурации чуть многословнее, нужно понимать семантику типов сервисов (simple/notify/forking) и аккуратно работать с daemon-reload. Если предпочитаете хранить логи в файлах, а не в journald, понадобится минимальная донастройка.

Короткая сводка различий

  • Простота старта: Supervisor проще на первых порах; systemd требует привыкания, но без сторонних зависимостей.
  • Ресурсные лимиты и изоляция: systemd сильнее (cgroups, CPU/IO/Memory, sandboxing).
  • Логи: Supervisor — файлы; systemd — journald (с возможностью перенаправления в syslog/файл).
  • Операции и диагностика: оба хороши; в systemd единая точка управления для всей системы.

Если у вас типичный стек на PHP и первую очередь надо поднять «прямо сейчас» — начните с Supervisor. Если строите стандартизируемую базу под десятки сервисов, лимиты и безопасность — берите systemd.

Пример юнита systemd для Laravel queue и просмотр логов через journalctl

Базовая схема для PHP workers и Laravel queue

PHP-воркеры, как правило, запускаются через CLI (без FPM): команда вроде php artisan queue:work или отдельный раннер. Важно задать:

  • Очереди и приоритеты: например, --queue=high,default,low.
  • Ограничения устойчивости: --tries=3, --backoff=5, --timeout=120.
  • Обновление воркеров: queue:restart при деплое, либо --max-jobs/--max-time/--memory для регулярной «ротации» процесса и освобождения памяти.
  • Количество процессов: по числу ядер или немного меньше; ориентируйтесь на CPU-bound/IO-bound характер задач.
  • Пользователь: не root, обычно www-data или отдельный системный пользователь проекта.
FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды Финляндия

Примеры конфигураций

systemd unit для Laravel queue

[Unit]
Description=Laravel queue worker (high)
After=network.target
StartLimitIntervalSec=300
StartLimitBurst=10

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/project/current
Environment=APP_ENV=production
ExecStart=/usr/bin/php artisan queue:work --queue=high,default --sleep=2 --tries=3 --max-jobs=500 --max-time=3600 --memory=256
ExecReload=/usr/bin/php artisan queue:restart
Restart=always
RestartSec=5
# Управление ресурсами
CPUWeight=100
IOWeight=100
MemoryMax=512M
TasksMax=100
# Акуратное завершение
KillSignal=SIGTERM
TimeoutStopSec=30
# Логи в journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=laravel-queue-high

[Install]
WantedBy=multi-user.target

Поддерживайте по одному юниту на класс очереди (high/default/low). Для масштабирования добавляйте копии с суффиксами (laravel-queue-high@1.service, @2) или используйте шаблонные юниты. На деплой встраивайте systemctl reload — он дернет ExecReload, что безопасно для воркеров Laravel (они поймают флаг и gracefully завершатся).

Supervisor program для Laravel queue

[program:laravel-queue-high]
command=/usr/bin/php artisan queue:work --queue=high,default --sleep=2 --tries=3 --max-jobs=500 --max-time=3600 --memory=256
directory=/var/www/project/current
user=www-data
numprocs=2
autostart=true
autorestart=true
stopsignal=TERM
stopasgroup=true
killasgroup=true
stdout_logfile=/var/log/supervisor/laravel-queue-high.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=5
redirect_stderr=true
environment=APP_ENV="production"

Команды управления: supervisorctl reread и supervisorctl update после изменения конфигов, supervisorctl status/start/stop/restart — для повседневных операций. На деплой — php artisan queue:restart или supervisorctl signal для мягкой смены процессов.

Перезапуски и деплой без простоев

Laravel queue:restart и graceful shutdown

php artisan queue:restart выставляет флаг в кеше, который улавливают воркеры: они завершают текущие задания и выходят. Это лучший способ «перезагрузить код» без сброса незавершенных задач и без потерь. В связке с --max-jobs и --max-time воркеры будут периодически перезапускаться сами, снижая риск накопления фрагментации памяти в долгоживущем процессе PHP.

Reload/Restart в systemd

В systemd используйте ExecReload с queue:restart, чтобы «мягко» обновить воркеры во время деплоя. Полный restart пригодится при критических сбоях, но помните: он прерывает процесс немедленно (если не дать время на TimeoutStopSec).

Rolling рестарт группы воркеров

Если у вас несколько воркеров на очередь (например, 4 процесса на high), обновляйте их по одному: отправьте reload юнитам с суффиксами, дайте им завершить задание, затем переходите к следующему. Это исключит провалы производительности на пике. В Supervisor того же эффекта можно добиться последовательными signal/restart конкретных процессов.

Перезапуск по ресурсам

Типичные ловушки — медленная деградация и утечки памяти. Для php workers почти обязательно задавайте --memory, --max-jobs и (по ситуации) --max-time. В systemd можно добавить MemoryMax, чтобы ядро завершало процесс при превышении (будет зафиксировано как failure и перезапущено). В Supervisor схожий эффект достигается периодической «ротацией» воркеров через --max-jobs и автоперезапуском.

Если запускаете периодические задачи, посмотрите системные таймеры как замену cron: это упрощает единое управление через systemd — подробности в материале systemd timers и cron.

Логи: journald, logrotate и файлы Supervisor

У логов два направления — трассировка проблем в реальном времени и долгосрочное хранение с ротацией. Ключевые задачи: видеть ошибки мгновенно, не терять историю и не заполнять диск.

systemd/journald

Для юнитов с StandardOutput=journal используйте journalctl -u <unit> -f для «хвоста» и journalctl -u <unit> --since "-1h" для разборов. Чтобы логи переживали перезагрузку, включите persistent-хранилище journald:

# /etc/systemd/journald.conf
Storage=persistent
SystemMaxUse=1G
RuntimeMaxUse=256M
RateLimitIntervalSec=30
RateLimitBurst=1000

После правок перезапустите journald. Такие лимиты удержат объем и не дадут логам бесконтрольно разрастись. При желании выведите логи юнита в syslog/файл через SyslogIdentifier и соответствующее правило в системе логирования.

Конфиг Supervisor для воркеров и ротация логов logrotate

Supervisor: файлы и ротация

Supervisor логирует stdout/stderr в файлы. Обязательно задавайте лимиты по размеру и бэкапам: stdout_logfile_maxbytes, stdout_logfile_backups, redirect_stderr=true. Если нужен классический logrotate — добавьте правило:

/var/log/supervisor/*.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
    delaycompress
    copytruncate
}

Не используйте «вечные» файлы без ротации: достаточно одной «слетевшей» задачи, чтобы размотать диск на сотни гигабайт.

Обслуживание и диагностика

  • Статус и перезапуски: systemctl status <unit>, systemctl restart <unit>, supervisorctl status, supervisorctl restart <program>.
  • Логи: journalctl -u <unit> -f или «хвост» файла Supervisor.
  • Права и окружение: проверьте User, WorkingDirectory, Environment, пути к PHP/интерпретатору, переменным доступа к Redis/DB.
  • Ограничения: ulimit -n (кол-во файлов), LimitNOFILE в systemd, размеры памяти (в systemd — MemoryMax).
  • OOM killer: если воркеры гибнут без логов, проверьте dmesg/journald на OOM и снизьте память или число процессов.
  • Таймауты и зависания: для Laravel уточните --timeout, --backoff, оберните внешние вызовы в разумные таймауты (HTTP/DB).

Безопасность и производительность

  • Не запускайте воркеры от root. Создайте отдельного пользователя или используйте www-data.
  • В systemd применяйте песочницу: NoNewPrivileges=true, PrivateTmp=true, ProtectSystem=full, ProtectHome=true — постепенно, проверяя совместимость.
  • Регулируйте нагрузку: CPUWeight/IOWeight, при необходимости CPUQuota, чтобы php workers не выжирали все ядра.
  • Делите очереди на классы: high/critical для пользовательских действий; default для обычных задач; low — для отложенных и тяжелых.
  • Ставьте базовые лимиты устойчивости: --tries, --backoff, --memory, --max-jobs. Это ваш страховочный трос.

Подбираете ресурсы под воркеры и очереди? Смотрите чек-лист по выбору конфигурации сервера в материалах про размеры инстанса: как выбрать план VDS по CPU и RAM.

Чек-лист запуска очередей на новом VDS

  1. Выбрать оркестратор: Supervisor (быстрый старт) или systemd (нативная интеграция, лимиты).
  2. Создать отдельного пользователя и директорию проекта с корректными правами.
  3. Определить очереди и приоритеты, задать параметры запуска воркеров (--tries, --backoff, --timeout, --memory, --max-jobs).
  4. Оформить конфиг: юнит systemd или program Supervisor. Включить автозапуск и autorestart.
  5. Настроить логи: journald с лимитами или файлы Supervisor с ротацией.
  6. Прописать процедуру деплоя: queue:restart и последовательный reload/restart воркеров.
  7. Поставить ресурсные лимиты: CPU/IO/Memory, лимиты на открытые файлы.
  8. Проверить graceful shutdown: симулировать рестарт во время выполнения задачи.
  9. Задокументировать команды оператора: как смотреть logs, как делать restart, в каких файлах лежат конфиги.

Итог

И Supervisor, и systemd надежно тянут фоновые процессы на VDS. Выбор — дело привычки и требований к интеграции с системой. Для проектов на PHP и laravel queue критичны три вещи: предсказуемые перезапуски (graceful restart с queue:restart), аккуратные лимиты ресурсов и понятная стратегия логирования/ротации. Сформируйте один выверенный шаблон, проверьте его под нагрузкой — и очереди будут работать стабильно, без сюрпризов на проде.

Поделиться статьей

Вам будет интересно

Как безопасно выполнить bootstrap MariaDB Galera после полного останова

Как безопасно выполнить bootstrap MariaDB Galera после полного останова

После одновременной остановки всех узлов Galera обычного запуска MariaDB недостаточно. Сначала найдите сервер с последней транзакц ...
CoreDNS в Kubernetes: исправляем CrashLoopBackOff, SERVFAIL и DNS-петлю

CoreDNS в Kubernetes: исправляем CrashLoopBackOff, SERVFAIL и DNS-петлю

Разберём, почему CoreDNS перезапускается или отвечает SERVFAIL, как обнаружить замкнутую пересылку DNS-запросов, проверить доступн ...
Apache Kafka KRaft на VDS: отдельные controller и broker

Apache Kafka KRaft на VDS: отдельные controller и broker

Соберём новый Kafka-кластер без ZooKeeper на шести Linux VDS: три узла controller образуют отказоустойчивый metadata quorum, а три ...