Урок по треку Системный анализ 8 мин

Асинхронные интеграции и брокеры сообщений

Очереди и топики, Kafka и RabbitMQ, гарантии доставки, outbox, саги.

Синхронный вызов: «позвонил и ждёшь ответа». Асинхронный: «отправил сообщение и занимаешься своим делом». Асинхронность развязывает системы во времени: получатель может лежать, а сообщение дождётся его в брокере.

Когда асинхронно

  • Отправителю не нужен немедленный результат (письмо, начисление бонусов, аналитика).
  • Событие нужно нескольким потребителям (заказ создан: склад, CRM, аналитика).
  • Нужно сгладить пики нагрузки: очередь накопит, обработчики разгребут.
  • Долгие операции (генерация отчёта, распознавание документа).

Минусы: сложнее отлаживать, появляется eventual consistency (данные согласуются не сразу), нужно думать о дублях и порядке.

Очередь и топик

  • Очередь (point-to-point): каждое сообщение получает один потребитель. Задачи на обработку.
  • Публикация-подписка (pub/sub): каждое сообщение получают все подписчики. События.

RabbitMQ и Kafka

RabbitMQKafka
Модельброкер очередей: exchange → очередираспределённый журнал: топики из партиций
После прочтениясообщение удаляется после подтвержденияхранится заданное время, можно перечитать
Маршрутизациягибкая: direct, topic, fanout, headersпо ключу в партицию
Порядокв пределах очередив пределах партиции
Сильная стороназадачи, сложная маршрутизация, RPC поверх очередейпоток событий, высокая пропускная способность, перечитка, event sourcing

В Kafka потребители объединяются в consumer group: партиции делятся между участниками группы, каждая группа читает весь топик независимо. Сообщения с одинаковым ключом (например, order_id) попадают в одну партицию и читаются по порядку.

Гарантии доставки

  • At most once: не больше одного раза, возможна потеря.
  • At least once: не меньше одного раза, возможны дубли. Самый частый выбор.
  • Exactly once: ровно один раз. На практике достигается как «at least once + идемпотентный потребитель» или транзакциями внутри одной платформы (Kafka transactions).

Отсюда главное правило: потребитель идемпотентен. Храним id обработанных сообщений или делаем операцию такой, что повтор ничего не меняет (UPSERT, проверка статуса).

Проблема двойной записи и outbox

Сервис должен сохранить заказ в БД и отправить событие в брокер. Если сделать это двумя операциями, одна может упасть: заказ есть, события нет (или наоборот).

Transactional outbox: в той же транзакции, что и заказ, пишем событие в таблицу outbox. Отдельный процесс (поллер или CDC, например Debezium) читает outbox и публикует в брокер. Доставка at least once, значит потребитель идемпотентен.

Саги

Распределённая операция из шагов в разных сервисах без общей транзакции. Если шаг упал, выполняют компенсирующие действия: отменить резерв, вернуть деньги.

  • Хореография: сервисы реагируют на события друг друга. Просто на 2-3 шагах, дальше трудно понять, кто что делает.
  • Оркестрация: центральный оркестратор говорит, что делать дальше. Нагляднее, легче менять, но оркестратор становится важной точкой.

Ошибки и DLQ

Сообщение, которое не удаётся обработать (битый формат, бизнес-ошибка), не должно бесконечно возвращаться в очередь. После N попыток с задержкой его перекладывают в DLQ (dead letter queue), где разбирают вручную или отдельным процессом.

Контракт сообщения

Аналитик описывает: имя события в прошедшем времени (OrderCreated), версию схемы, ключ, обязательные поля, кто публикует, кто потребляет, гарантии, порядок, что делать с дублями. Для описания есть AsyncAPI, схемы хранят в Schema Registry (Avro, Protobuf, JSON Schema).

Два стиля событий:

  • Event notification: «заказ 42 изменился», за деталями потребитель идёт в API.
  • Event-carried state transfer: в событии все нужные данные, потребитель не ходит обратно.

Частые ошибки

  • Ждать ответа через брокер как через синхронный вызов, не продумав таймаут.
  • Не учесть дубли и порядок.
  • Отправлять событие до коммита транзакции.
  • Нет DLQ и мониторинга отставания потребителей (lag).

Что спросят на собесе

  • Когда выберешь асинхронную интеграцию вместо REST?
  • Чем Kafka отличается от RabbitMQ?
  • Какие гарантии доставки бывают? Как бороться с дублями?
  • Что такое transactional outbox?
  • Что такое сага, чем хореография отличается от оркестрации?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.