Налаштування пріоритезації завдань у черзі (Priority Queue)
Уявіть: 90% користувачів покидають сайт, якщо лист скидання пароля не приходить протягом 5 секунд. А ваша черга забита 30-хвилинними звітами. Результат — втрата клієнтів і негатив. Ми стикалися з цим у проєкті з 150 000 активних користувачів: critical-завдання (скидання пароля, SMS-коди) стояли в одній черзі з експортами. Після впровадження пріоритезації latency для critical впало з 30 секунд до 2 секунд — у 15 разів швидше. Нижче — як ми це робимо.
За 5+ років роботи з чергами ми опрацювали понад 50 проєктів, від стартапів до enterprise. Наш підхід — спроектувати модель пріоритетів, налаштувати воркери та захистити систему від голодування. Без зайвих абстракцій, лише перевірені патерни.
Чому пріоритезація завдань у черзі критична для продуктивності?
Без пріоритезації всі завдання обробляються в порядку надходження (FIFO). Це призводить до неприпустимих затримок для критичних операцій. Наприклад, у high-traffic проєкті кожні 100 мс затримки знижують конверсію на 7%. Наші клієнти після налаштування пріоритетів бачать скорочення часу відповіді critical-завдань на 80–95%.
Модель пріоритетів
Типовий поділ на три рівні:
| Черга | Завдання | Допустиме очікування |
|---|---|---|
critical |
Скидання пароля, SMS-коди, платіжні сповіщення | < 5 секунд |
default |
Транзакційні листи, сповіщення | < 30 секунд |
low |
Звіти, експорт, розсилки, індексація | хвилини/години |
Вибір рівнів залежить від SLA вашого бізнесу. Для інтернет-магазину можна додати чергу high для замовлень.
Як налаштувати пріоритети в Laravel?
Laravel підтримує soft-пріоритет: воркер перебирає черги у вказаному порядку. Команда:
php artisan queue:work --queue=critical,default,low
Якщо в critical є завдання, воркер не переходить до default. Пріоритет задається при диспатчі:
SendPasswordResetEmail::dispatch($user)->onQueue('critical');
Або всередині Job через властивість $queue. Це простий і швидкий спосіб, але при довгих завданнях у low-черзі critical може чекати. Рішення — виділені воркери Horizon.
Порівняння soft-пріоритету та виділених воркерів
| Параметр | Soft-пріоритет | Виділені воркери (Horizon) |
|---|---|---|
| Latency для critical | Може досягати хвилин | Гарантовано < 5 секунд |
| Конфігурація | Один воркер | Supervisor на чергу |
| Ризик starvation | Високий при завантаженні | Мінімальний |
| Ресурси | Економніше | Вимагає більше процесів |
Як використовувати виділені воркери для критичних завдань?
Horizon дозволяє створити окремі пули воркерів для кожної черги. Порівняйте: soft-пріоритет — latency для critical може досягати хвилин при завантаженні low-черги. Виділені воркери гарантують < 5 секунд — у 10 разів швидше. Приклад конфігурації:
// config/horizon.php
'environments' => [
'production' => [
'critical-supervisor' => [
'connection' => 'redis',
'queue' => ['critical'],
'balance' => 'simple',
'minProcesses' => 2,
'maxProcesses' => 8,
'timeout' => 30,
],
'default-supervisor' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'auto',
'minProcesses' => 1,
'maxProcesses' => 5,
'timeout' => 60,
],
'low-supervisor' => [
'connection' => 'redis',
'queue' => ['low'],
'balance' => 'simple',
'processes' => 2,
'timeout' => 3600,
],
],
],
Кожен supervisor працює незалежно: critical не блокується low-завданнями. Це стандартний патерн для high-traffic проєктів.
Що таке starvation і як його запобігти?
Starvation (голодування) — ситуація, коли низькопріоритетні завдання ніколи не обробляються через постійний приплив критичних. Це призводить до нескінченного накопичення звітів та експортів. Два основні рішення:
Aging — підвищення пріоритету з часом. Реалізуємо через scheduled job:
// підвищуємо пріоритет завдань, що очікують більше 30 хвилин
Schedule::call(function () {
Job::where('queue', 'low')
->where('created_at', '<', now()->subMinutes(30))
->update(['queue' => 'default']);
})->everyFifteenMinutes();
Виділений воркер для low — один процес гарантує, що low-завдання рано чи пізно виконаються. Комбінація двох методів дає 100% захист.
Динамічний пріоритет на основі даних
Пріоритет можна призначати не статично, а залежно від користувача. Наприклад, enterprise-клієнтам — critical, звичайним — default. Це гнучкіше жорсткої схеми і економить ресурси.
Пріоритет у BullMQ (Node.js)
BullMQ використовує числові пріоритети через Redis Sorted Set. Це точніше Laravel, але вимагає окремої інфраструктури.
await queue.add('send-password-reset', { userId: 123 }, { priority: 1 });
await queue.add('generate-report', { reportId: 789 }, { priority: 10 });
Чим менше число, тим вищий пріоритет. У Laravel простіше, якщо стек вже на PHP.
Моніторинг та алертинг
Глибину черг відстежуємо через Redis: Redis::llen('queues:critical'). Horizon показує це в дашборді. Налаштовуємо алерти на зростання черг — сигнал нестачі воркерів. Рекомендуємо пороги: якщо critical > 50, default > 200 або low > 1000 — термінове оповіщення. Це запобігає простоям.
Що входить у роботу
- Аудит поточної архітектури черг
- Проектування моделі пріоритетів з SLA
- Конфігурація воркерів (Horizon або BullMQ)
- Захист від голодування (aging + виділений воркер)
- Моніторинг та документація
Терміни: базове налаштування трьох черг — 3–5 годин. Логіка антиголодування та моніторинг — ще 2–4 години. Вартість розраховується індивідуально.
Оцінимо ваш проєкт — зв'яжіться з нами. Замовте налаштування черг — отримайте консультацію щодо вашого стеку.
Докладніше про Laravel Horizon (офіційна документація)







