Queue и schedule это два процесса
Долгий job не задержит тик cron. Деплой перезапускает воркер, чтобы новые job не крутились на старых классах.
В compose-файле уже были контейнеры queue и schedule. Считать их одним процессом было ошибкой. Пересборка sitemap на месте воровала минутный тик. Reserved job с жирным unserialize растил RSS, пока хост не начинал своп. php-fpm этого видеть не должен.
У воркеров теперь ограниченное число попыток, таймаут короче резерва Redis и потолок памяти, который убивает процесс до свопа. Медленная работа уходит в очередь. Процесс schedule только диспатчит.
Наложение и возраст
Долгие задачи пропускаются, если предыдущий запуск ещё жив. Две копии ночной чистки на одних строках это unique key в 03:10. Сигнал здоровья это heartbeat на каждом тике. Если метка старше нескольких минут, контейнер мёртв или заклинил.
Алерт по возрасту самого старого job, не по глубине. Глубокая, но уходящая очередь нормальна. Один зависший job нет. Failed jobs несут payload, класс исключения и correlation id запроса, который их поставил.
Деплой
Релиз явно перезапускает queue-воркер. Без этого шага воркер держит старые классы в памяти и обрабатывает новые job старым кодом. Баг жил несколько минут после каждого переключения и выглядел как случайный сбой.
Разделение это правило. HTTP остаётся в php-fpm. Job в queue. Тики в schedule. Если задача медленная, на тике она не бежит.
