Ознаки, що воркери не встигають: задачі чекають у черзі хвилинами, листи підтвердження приходять із запізненням, Horizon повідомляє про довге очікування (LongWaitDetected).
1. Більше воркерів. Найпростіший крок - запустити кілька процесів queue:work (через Supervisor numprocs, кілька контейнерів чи Horizon maxProcesses). Кожен воркер обробляє одну задачу за раз, тож N воркерів - до N задач паралельно.
Межа - ресурси: кожен воркер - окремий PHP-процес з власною пам'яттю, і кожен тримає з'єднання з базою.
2. Розділити черги за пріоритетом:
SendPasswordReset::dispatch($user)->onQueue('high');
GenerateReport::dispatch($report)->onQueue('low');
php artisan queue:work --queue=high,default,low
Воркер спершу бере задачі з high, і масовий імпорт у low не затримує скидання пароля.
3. Окремі воркери для окремих черг. Пріоритети не рятують, якщо повільні задачі займають усіх воркерів. Тоді виділяють окремі групи:
- 2 воркери лише для
high; - 6 воркерів для
default; - 2 воркери для
lowз більшим--timeoutі лімітом пам'яті.
4. Horizon - балансування автоматично:
'supervisor-1' => [
'queue' => ['high', 'default', 'low'],
'balance' => 'auto',
'autoScalingStrategy' => 'time',
'minProcesses' => 1,
'maxProcesses' => 20,
],
Horizon перерозподіляє процеси між чергами залежно від навантаження і показує час очікування й пропускну здатність кожної черги.
5. Окремі сервери для воркерів. Воркери не мають бути на вебсерверах: важкі задачі (обробка відео, PDF) не повинні впливати на швидкість сторінок. Окремі сервери можна масштабувати незалежно.
Перш ніж додавати воркерів, перевірте задачі:
- чому задача повільна - N+1 у задачі, синхронні виклики зовнішніх API, обробка файлів у пам'яті;
- чи можна розбити - одна задача «надіслати розсилку 50 000 листів» гірша за 50 000 маленьких (чи пакет
Bus::batch); - вузьке місце може бути не у воркерах: якщо всі задачі ходять у базу чи сторонній API з лімітом, більше воркерів лише збільшить конкуренцію. Тоді потрібне обмеження частоти (
RateLimitedmiddleware) і пул з'єднань з базою.