Перейти к содержимому

Паттерны обмена

Паттерны обмена сообщениями — это типовые способы организации доставки: Message Queue (сообщение одному получателю) и Publish-Subscribe (всем подписчикам) — базовые; Message Filter и Router — для маршрутизации; Splitter и Aggregator — для трансформации; Dead Letter Channel — для обработки ошибок; Idempotent Consumer — для защиты от дубликатов.

Введение: Способы сказать “привет”

Представьте, что вы в офисе. Есть много способов передать информацию коллеге.

Можно подойти и сказать лично — это точка-точка. Можно крикнуть всем в комнате — это publish-subscribe. Можно написать на доске объявлений — это message queue. Можно попросить секретаря разослать письма — это message router.

Паттерны обмена сообщениями (Messaging Patterns) — это типовые способы организации обмена сообщениями между системами через брокер. Они определяют, как сообщение попадает от отправителя к получателю, сколько получателей его получат, как оно маршрутизируется.

Для системного аналитика паттерны обмена — это строительные блоки для интеграционных решений. Понимание паттернов позволяет проектировать архитектуру, которая будет надёжной, масштабируемой и понятной команде.

Классификация паттернов

КатегорияПаттерны
БазовыеMessage Queue, Publish-Subscribe
МаршрутизацияMessage Filter, Message Router, Content-Based Router
ТрансформацияMessage Splitter, Message Aggregator
НадёжностьDead Letter Channel, Idempotent Consumer

Базовые паттерны

Message Queue (Очередь сообщений)

Сообщение помещается в очередь и доставляется одному получателю.

    graph LR
    A[Отправитель] --> Q[Очередь]
    Q --> B[Получатель 1]
    Q --> C[Получатель 2]
    Q --> D[Получатель 3]
  

Характеристики:

СвойствоЗначение
Получателей на сообщениеОдин
КонкуренцияЕсть
Балансировка нагрузкиАвтоматическая

Когда использовать: Распределение задач между воркерами.

Publish-Subscribe (Pub-Sub)

Сообщение публикуется в топик и доставляется всем подписчикам.

    graph LR
    A[Отправитель] --> T[Топик]
    T --> B[Подписчик 1]
    T --> C[Подписчик 2]
    T --> D[Подписчик 3]
  

Характеристики:

СвойствоЗначение
Получателей на сообщениеВсе подписчики
КонкуренцияНет
МасштабированиеЛегко добавить подписчика

Когда использовать: Оповещение о событиях.

Паттерны маршрутизации

Message Filter (Фильтр сообщений)

Сообщения фильтруются по критериям. Неподходящие отбрасываются.

    graph LR
    A[Входящие] --> F{Фильтр}
    F -->|подходит| B[Целевая очередь]
    F -->|не подходит| C[Отброшены]
  

Пример: Только заказы на сумму > 1000 отправлять в очередь VIP-обработки.

Когда использовать: Нужно разделить поток на важный и неважный.

Message Router (Маршрутизатор)

Сообщение направляется в одну из нескольких очередей на основе правил.

    graph LR
    A[Входящие] --> R{Роутер}
    R -->|тип А| B[Очередь А]
    R -->|тип Б| C[Очередь Б]
    R -->|тип В| D[Очередь В]
  

Пример: Заказы из Москвы — в очередь московского склада, из СПб — в очередь питерского.

Content-Based Router (Маршрутизация по содержимому)

Разновидность маршрутизатора, где решение принимается на основе содержимого сообщения.

Правила:
  - Если order.type = "electronic" → очередь электроники
  - Если order.type = "furniture" → очередь мебели
  - Если order.type = "clothing" → очередь одежды

Паттерны трансформации

Message Splitter (Разделитель)

Одно сообщение разбивается на несколько.

    graph LR
    A[Сообщение-корзина] --> S[Сплиттер]
    S --> B[Сообщение 1]
    S --> C[Сообщение 2]
    S --> D[Сообщение 3]
  

Пример: Заказ на несколько товаров → отдельное сообщение для каждого товара.

Message Aggregator (Агрегатор)

Несколько сообщений объединяются в одно.

    graph LR
    A[Сообщение 1] --> AG[Агрегатор]
    B[Сообщение 2] --> AG
    C[Сообщение 3] --> AG
    AG --> D[Сообщение-корзина]
  

Пример: Отдельные события от датчиков → агрегированный отчёт за час.

Паттерны надёжности

Dead Letter Channel (Канал мёртвых писем)

Сообщения, которые не удалось обработать, отправляются в специальную очередь.

    graph LR
    A[Основная очередь] -->|ошибка| B[DLQ]
    B -->|анализ| C[Администратор]
  

Причины попадания в DLQ:

ПричинаОписание
Превышено количество попытокПолучатель не смог обработать после N попыток
Невалидное сообщениеСообщение нельзя обработать в принципе
ТаймаутОбработка заняла слишком много времени

Idempotent Consumer (Идемпотентный потребитель)

Обработчик, который устойчив к дубликатам сообщений.

Алгоритм:
  1. Получить сообщение с idempotency_key
  2. Проверить в хранилище: ключ уже обработан?
  3. Если да → пропустить, вернуть OK
  4. Если нет → обработать, сохранить ключ

Комбинирование паттернов

Пример: Обработка заказов

    graph TD
    A[Заказы] --> F{Фильтр}
    F -->|сумма > 1000| R{Роутер}
    F -->|сумма ≤ 1000| Q1[Обычная очередь]
    
    R -->|электроника| Q2[Очередь электроники]
    R -->|мебель| Q3[Очередь мебели]
    
    Q2 --> S[Сплиттер]
    S --> P1[Товар 1]
    S --> P2[Товар 2]
    
    P1 --> AG[Агрегатор]
    P2 --> AG
    AG --> Q4[Готовые заказы]
  

Паттерны и брокеры

БрокерПоддержка паттернов
RabbitMQВсе паттерны (гибкая маршрутизация через exchanges)
KafkaPub-Sub, Consumer Groups (аналог очереди), но фильтрация на стороне потребителя
AWS SQSОчередь, DLQ
AWS SNSPub-Sub, фильтрация (по атрибутам)

Выбор паттерна

ЗадачаПаттерн
Распределить задачи между воркерамиMessage Queue
Оповестить все системы о событииPublish-Subscribe
Отбросить неважные сообщенияMessage Filter
Направить сообщения в разные очередиMessage Router
Разбить составное сообщение на частиMessage Splitter
Собрать части в одно сообщениеMessage Aggregator
Обработать ошибочные сообщенияDead Letter Channel
Избежать дублирования обработкиIdempotent Consumer

Распространённые ошибки

Ошибка 1: Очередь для событий

Используют очередь для оповещения многих систем. Одна система получила, остальные нет.

Решение: Publish-Subscribe.

Ошибка 2: Pub-Sub для задач

Публикуют задачи в топик. Все подписчики берут и обрабатывают одну задачу.

Решение: Message Queue.

Ошибка 3: Нет DLQ

Сообщения-ошибки теряются или зависают в очереди.

Решение: Dead Letter Channel.

Ошибка 4: Нет идемпотентности

При at-least-once дубликаты приводят к двойной обработке.

Решение: Idempotent Consumer.

Ошибка 5: Слишком сложная маршрутизация

Роутер с сотней правил, который никто не может поддерживать.

Решение: Вынести логику в отдельный сервис.

Резюме

  1. Паттерны обмена — типовые способы организации обмена сообщениями через брокер.

  2. Базовые: очередь (одному получателю), топик (всем подписчикам).

  3. Маршрутизация: фильтр, роутер, content-based router.

  4. Трансформация: сплиттер (разделение), агрегатор (объединение).

  5. Надёжность: DLQ (для ошибочных сообщений), идемпотентный потребитель (защита от дубликатов).

  6. Комбинирование: паттерны можно и нужно комбинировать.

Проверка знаний

Вопрос 1 из 4
Что такое паттерны обмена сообщениями?
Какой паттерн уместен, если сообщение нужно доставить одному обработчику?
Какой паттерн полезен, если по одному потоку нужно разослать сообщения в разные системы?
Что важно помнить о паттернах обмена?

Вопросы, где были ошибки