System Design
Message Queue
Цели урока
- Понимать зачем нужны Message Queues
- Различать Queue (point-to-point) и Pub/Sub (fan-out)
- Знать delivery guarantees: at-most-once, at-least-once, exactly-once
- Уметь проектировать idempotent consumers
- Понимать DLQ и retry стратегии
- Знать когда использовать RabbitMQ vs Kafka
Предварительные знания
- Понимание асинхронного программирования
- Базовые знания о distributed systems
Зачем нужны очереди сообщений
**Message Queue** - промежуточный слой для асинхронной коммуникации. Producer отправляет сообщение → Queue хранит → Consumer обрабатывает когда готов.
Пользователь регистрируется. Нужно отправить welcome email. Синхронно = 2 секунды ожидания. С очередью = мгновенный ответ.
- Decoupling: сервисы не знают друг о друге, общаются через очередь
- Buffering: очередь сглаживает пики нагрузки (Black Friday)
- Async: тяжёлые задачи (video encoding) выполняются в фоне
Email при регистрации
Синхронный vs асинхронный подход
БЕЗ ОЧЕРЕДИ: • User registers → API отправляет email → 200 OK • Latency: 100ms (API) + 2000ms (SMTP) = 2100ms • Проблема: SMTP упал = регистрация провалилась С ОЧЕРЕДЬЮ: • User registers → API кладёт job в queue → 200 OK • Worker берёт job → отправляет email → retry при ошибке • Latency: 100ms + 5ms (enqueue) = 105ms • SMTP упал = job retry позже, пользователь не ждёт
Когда нужна очередь
- **Тяжёлые задачи**: email, PDF, видео-транскодинг
- **Пики нагрузки**: flash sale, очередь буферизирует
- **Decoupling**: OrderService не ждёт InventoryService
- **Retry логика**: failed job остаётся, можно повторить
- **Event-driven**: один event → много consumers
Какую проблему НЕ решает Message Queue?
Queue vs Pub/Sub
Два основных паттерна: **Queue** (point-to-point) и **Pub/Sub** (publish-subscribe). Разные use cases.
Queue (Point-to-Point)
Pub/Sub (Fan-out)
| Критерий | Queue | Pub/Sub |
|---|---|---|
| Получатели | Один (load balanced) | Все subscribers |
| Coupling | Producer знает queue | Publisher не знает subscribers |
| Use case | Job processing | Event broadcasting |
| Пример | Send email job | Order created event |
Заказ создан. Нужно: уведомить склад, отправить email, записать в аналитику. Что использовать?
Delivery Guarantees
Гарантии доставки - trade-off между надёжностью и производительностью. Три уровня:
**At-least-once** = стандарт индустрии. Consumer ДОЛЖЕН быть idempotent: обработка одного сообщения дважды = тот же результат.
**Idempotency Key**: Храни ID обработанных сообщений в Redis с TTL. Проверяй перед обработкой.
При at-least-once delivery, зачем нужен idempotent consumer?
DLQ и Retry Logic
Что делать, если сообщение не удалось обработать? **Retry** с exponential backoff. Если всё равно не получается - **Dead Letter Queue (DLQ)**.
Visibility Timeout
Dead Letter Queue
**Мониторинг DLQ** обязателен! Alert на size > 0 или growth rate. Растущий DLQ = что-то сломано.
Сообщение попало в DLQ. Что делать?
Backpressure
**Backpressure** - механизм защиты от перегрузки. Если consumer не справляется, нужно замедлить producer или масштабировать consumers.
Стратегии backpressure
| Стратегия | Как работает | Когда |
|---|---|---|
| Bounded Queue | Лимит размера → reject при overflow | Критичные системы |
| Rate Limiting | Producer ограничен N msg/sec | Контролируемый input |
| Auto-scaling | Queue grows → add workers | AWS Lambda + SQS |
| Sampling | Drop часть сообщений | Метрики, логи |
**Best Practice**: Мониторь Queue Depth и Age of Oldest Message. Растут = consumers не справляются. Настрой auto-scaling или alerts.
Queue растёт быстрее, чем consumers обрабатывают. Первое действие?
RabbitMQ vs Kafka
Два главных игрока: **RabbitMQ** (traditional message broker) и **Kafka** (distributed event log). Разные модели, разные use cases.
RabbitMQ
Kafka
| Критерий | RabbitMQ | Kafka |
|---|---|---|
| Model | Message Broker | Event Log |
| Delivery | Push | Pull |
| After consume | Message deleted | Message retained |
| Throughput | 10K-100K msg/s | Millions msg/s |
| Replay | Сложно | Легко |
| Use case | Task queue, RPC | Event streaming, Analytics |
**Выбор**: RabbitMQ для job queues, RPC, routing. Kafka для event streaming, high-volume, когда нужен replay.
Нужно обрабатывать 1M events/sec с возможностью replay. Что выбрать?
Ключевые выводы
- **Queue** - point-to-point, один consumer. **Pub/Sub** - fan-out, все subscribers
- **At-least-once + idempotent consumers** - индустриальный стандарт
- **DLQ** - для failed messages, мониторь размер
- **Backpressure** - auto-scale consumers при росте очереди
- **RabbitMQ** для task queues. **Kafka** для event streaming
Связанные темы
Очереди - основа async architecture
- Microservices — Async communication между сервисами
- Event Sourcing — Kafka как event log
- CQRS — Commands через queue, events через pub/sub