Урок 01

Зачем нужны очереди

Проблема

Долгие операции в HTTP-запросе — плохо:

  • Email — 2 секунды.
  • Ресайз картинки — 3 секунды.
  • Вызов внешнего API — 5 секунд.
  • Генерация PDF — 4 секунды.
  • Импорт CSV на 100k строк — минуты.

Синхронно:

app.post('/register', async (req, res) => {
    const user = await User.create(req.body);

    await sendWelcomeEmail(user);       // 2 сек
    await resizeAvatar(user.avatar);    // 3 сек
    await syncWithCRM(user);             // 5 сек

    res.json({ user });
    // Пользователь ждал 10 секунд
});

Проблемы:

  • 10 секунд — пользователь ушёл.
  • Timeout на балансировщике.
  • Упал внешний API — вся регистрация сломалась.
  • Нагрузка — 100 запросов = 1000 секунд работы.

Решение — очередь

Задача уходит в очередь, HTTP отвечает мгновенно.

app.post('/register', async (req, res) => {
    const user = await User.create(req.body);

    // Отправить задачи
    emailQueue.add('welcome', { userId: user.id });
    imageQueue.add('resize', { path: user.avatar });
    crmQueue.add('sync', { userId: user.id });

    res.json({ user });
    // Мгновенно
});

Воркеры обрабатывают в фоне.

Что дают очереди

  • Скорость ответа — HTTP не блокируется.
  • Надёжность — упала задача — можно повторить.
  • Масштабирование — добавить воркеров.
  • Приоритеты — срочные вперёд.
  • Отложенность — выполнить через час.
  • Расписание — каждую ночь.
  • Ретраи — 3 попытки при ошибке.
  • Разделение — фронт-ответ ≠ фон-работа.

Когда нужны

  • Email / SMS / push — рассылки.
  • Обработка файлов — ресайз, конвертация.
  • Импорт / экспорт — CSV, Excel.
  • Внешние API — долгие запросы.
  • PDF / видео — генерация.
  • Отчёты — тяжёлые агрегаты.
  • Индексация — поиск.
  • Вебхуки — отправка партнёрам.

Когда НЕ нужны

  • Мгновенные операции — чтение из БД.
  • Ответ нужен сразу — синхронный API.
  • Маленькая нагрузка — простой сервер справится.
  • Критичный порядок — очередь может изменить.

Архитектура очереди

Три части:

  • Producer — кладёт задачу.
  • Queue (broker) — хранит.
  • Consumer (worker) — забирает и выполняет.
App → [Queue] → Worker 1
              → Worker 2
              → Worker 3

Брокеры

Что хранит очередь:

  • Redis — быстрый, простой. BullMQ, Laravel Queue.
  • RabbitMQ — надёжный, сложный.
  • Kafka — для стриминга, логов.
  • SQS — managed AWS.
  • Database — таблица в БД. Laravel Queue.
  • Beanstalkd — лёгкий.

Правило:

  • Простое — Redis или database.
  • Надёжное — RabbitMQ.
  • Много данных — Kafka.

Плюсы и минусы

Плюсы:

  • Скорость.
  • Отказоустойчивость.
  • Масштабирование.
  • Порядок через приоритеты.

Минусы:

  • Сложнее. Нужен брокер, воркеры, мониторинг.
  • Согласованность. Данные могут быть не сразу.
  • Отладка. Асинхронность — тяжело ловить баги.
  • Инфраструктура. Redis, supervisor, метрики.

Синхронно vs асинхронно

Синхронно:

HTTP → операция (10 сек) → ответ

Асинхронно:

HTTP → задача в очередь → мгновенный ответ
         ↓
       Worker → операция

Пример: регистрация

Синхронно:

1. Валидация — 10 мс
2. Создание юзера — 50 мс
3. Welcome email — 2000 мс
4. Ресайз аватара — 3000 мс
5. Slack-уведомление админу — 1000 мс
6. Запись в аналитику — 500 мс

Итого: 6.5 секунд

Асинхронно:

1. Валидация — 10 мс
2. Создание юзера — 50 мс
3. Задача email в очередь — 1 мс
4. Задача ресайза в очередь — 1 мс
5. Задача Slack в очередь — 1 мс
6. Задача аналитики в очередь — 1 мс

Итого: 64 мс

100 раз быстрее.

Retry — повтор при ошибке

Задача упала — попробовать снова.

Попытка 1 → упала
Ждать 10 сек
Попытка 2 → упала
Ждать 30 сек
Попытка 3 → упала
→ failed jobs

Что даёт: временные сбои (сеть, API) не теряются.

Отложенная задача

queue.add('reminder', { userId }, {
    delay: 24 * 60 * 60 * 1000,   // через 24 часа
});

Что даёт: напоминания, отложенные email, follow-up.

Расписание (cron)

queue.add('daily-report', {}, {
    repeat: { cron: '0 3 * * *' },   // каждый день в 3:00
});

Что даёт: регулярные задачи.

Приоритеты

queue.add('urgent', data, { priority: 1 });   // выше
queue.add('normal', data, { priority: 5 });   // ниже

Что даёт: срочное вперёд.

Что дальше

  1. Зачем нужны очереди
  2. Очереди в Laravel: основы
  3. Laravel Jobs
  4. Драйверы очередей
  5. Laravel Horizon
  6. Schedule (расписание)
  7. BullMQ: основы
  8. BullMQ: практика
  9. Redis Streams
  10. Очереди в NestJS
  11. Мониторинг и отладка
  12. Практика: email-рассылка

Практика

Ответь на вопросы:

  1. Чем опасна синхронная отправка email в HTTP-запросе?
  2. Что такое producer, broker, consumer?
  3. Когда очередь не нужна?
  4. Что даёт retry?

Найди в своих проектах 3 места, где можно применить очередь.

Итог

  • Очередь — фоновая обработка.
  • Producer → Broker → Consumer.
  • Retry — надёжность.
  • Delay, repeat, priority — гибкость.
  • Брокеры: Redis, RabbitMQ, Kafka, database.
  • Когда синхронно — быстрые операции.
  • Когда асинхронно — долгие, рискованные.

Дальше — очереди в Laravel: основы.