Спроектировать обмен через брокер: выбрать очередь или топик, ключ партиции для порядка событий и состав события, учитывая, что доставка «хотя бы раз» даёт дубли.
Посредник между системами
Посредник между системами
Брокер — посредник: отправитель (producer) кладёт сообщение, получатель (consumer) забирает его, когда готов. Моделей две (Enterprise Integration Patterns):
• очередь, точка-точка — каждое сообщение обрабатывает один из получателей, несколько получателей делят нагрузку;
• топик, публикация-подписка — каждое сообщение получает каждая подписанная группа.
RabbitMQ: сообщение отправляют в exchange, а тот по правилам (bindings) раскладывает его по очередям. Получатель подтверждает обработку (ack) — и сообщение удаляется. Оборвалась связь до ack — сообщение вернётся в очередь и придёт снова.
Kafka: топик — журнал из партиций, партиции делятся между получателями группы. Сообщения после чтения не удаляются, а хранятся по сроку (retention); каждая группа помнит свою позицию (offset) и может перечитать. Порядок гарантирован только внутри партиции. Сообщения с одинаковым ключом попадают в одну партицию, поэтому ключ = orderId: события заказа лягут по порядку.
Обычная гарантия доставки — «хотя бы раз»: сообщение не потеряется, но может прийти дважды. «Ровно один раз» Kafka умеет только внутри себя (таблица ниже). Поэтому у каждого события уникальный eventId, по которому получатель отбрасывает повторы.
Событие — факт в прошедшем времени (OrderPaid): отправитель не знает, кто слушает. Команда — просьба конкретному получателю (SendSms). Контракт событий описывают в AsyncAPI — аналоге OpenAPI для брокеров.
RabbitMQ и Kafka
| Свойство | RabbitMQ | Kafka |
|---|---|---|
| модель | очереди, раскладка через exchange | журнал-топик из партиций |
| после обработки | удаляется после ack | хранится по сроку, можно перечитать |
| порядок | в пределах очереди, пока нет повторов | только внутри партиции |
| кто сколько получает | очередь делит между получателями | каждая группа — все сообщения |
| типично в «Ромашке» | задания на SMS и push внутри сервиса уведомлений | события заказов для уведомлений, курьеров и аналитики |
Гарантии доставки
| Гарантия | Что значит |
|---|---|
| at-most-once, «не больше раза» | может потеряться, зато без повторов |
| at-least-once, «хотя бы раз» | не потеряется, но может прийти дважды; обычный режим и Kafka, и RabbitMQ с подтверждениями |
| exactly-once, «ровно один раз» | Kafka умеет внутри себя (транзакции); на стыке с внешней системой — SMS-шлюзом, платёжкой, чужой базой — это только «хотя бы раз» плюс получатель, отбрасывающий дубли |
Из чего состоит событие
| Поле | Зачем | Пример |
|---|---|---|
| eventId | узнать и отбросить повтор | e-7f3a… |
| type | что случилось | OrderPaid |
| occurredAt | когда случилось | 2026-10-19T14:32:00+03:00 |
| orderId | о каком заказе; ключ сообщения | 9001 |
| schemaVersion | развивать формат без поломок | 1 |
| данные | что нужно получателям | totalAmount 17980 |
Конспект урока
Посредник между системами
Брокер — посредник: отправитель (producer) кладёт сообщение, получатель (consumer) забирает его, когда готов. Моделей две (Enterprise Integration Patterns):
• очередь, точка-точка — каждое сообщение обрабатывает один из получателей, несколько получателей делят нагрузку;
• топик, публикация-подписка — каждое сообщение получает каждая подписанная группа.
RabbitMQ: сообщение отправляют в exchange, а тот по правилам (bindings) раскладывает его по очередям. Получатель подтверждает обработку (ack) — и сообщение удаляется. Оборвалась связь до ack — сообщение вернётся в очередь и придёт снова.
Kafka: топик — журнал из партиций, партиции делятся между получателями группы. Сообщения после чтения не удаляются, а хранятся по сроку (retention); каждая группа помнит свою позицию (offset) и может перечитать. Порядок гарантирован только внутри партиции. Сообщения с одинаковым ключом попадают в одну партицию, поэтому ключ = orderId: события заказа лягут по порядку.
Обычная гарантия доставки — «хотя бы раз»: сообщение не потеряется, но может прийти дважды. «Ровно один раз» Kafka умеет только внутри себя (таблица ниже). Поэтому у каждого события уникальный eventId, по которому получатель отбрасывает повторы.
Событие — факт в прошедшем времени (OrderPaid): отправитель не знает, кто слушает. Команда — просьба конкретному получателю (SendSms). Контракт событий описывают в AsyncAPI — аналоге OpenAPI для брокеров.