event driven архитектура

Event-driven архитектура (EDA, событийно-ориентированная архитектура) — это паттерн проектирования программных систем, при котором взаимодействие между компонентами строится через производство, обнаружение и потребление событий. Компонент, фиксирующий изменение состояния, публикует событие; другие компоненты реагируют на него асинхронно, не зная ничего о деталях реализации друг друга.

Ключевые концепции EDA

Событие (event) — неизменяемая запись о произошедшем факте: «Заказ #12345 создан», «Платёж обработан», «Пользователь зарегистрирован». Событие описывает прошедшее — что случилось, а не что нужно сделать.

Продюсер (producer / publisher) — компонент, создающий и публикующий события. Не знает, кто и когда их обработает.

Потребитель (consumer / subscriber) — компонент, подписанный на определённые события и реагирующий на них. Не знает о других потребителях того же события.

Брокер сообщений (message broker) — инфраструктурный компонент, принимающий события от продюсеров и доставляющий их потребителям. Apache Kafka, RabbitMQ, AWS SNS/SQS, Google Pub/Sub, NATS.

Три паттерна event-driven взаимодействия

Event Notification

Событие несёт минимум информации — только факт изменения. Потребитель, получив уведомление, запрашивает полные данные по API. Слабое зацепление, но дополнительные сетевые вызовы.

Event-Carried State Transfer

Событие несёт всё необходимое состояние. Потребитель не делает дополнительных запросов. Избыточность данных, но максимальная автономность потребителей.

Event Sourcing

События — единственный источник правды. Текущее состояние вычисляется путём воспроизведения всей истории событий. Полная история изменений, возможность временных запросов и аудита.

Преимущества event-driven архитектуры

  • Слабое зацепление: продюсер и потребитель развиваются независимо. Добавление нового потребителя не требует изменения продюсера.
  • Масштабируемость: потребители масштабируются независимо. Kafka-топик с партициями позволяет параллельно обрабатывать миллионы событий.
  • Устойчивость к отказам: если потребитель временно недоступен, события сохраняются в брокере и обрабатываются при восстановлении.
  • Гибкость: новая функция добавляется как новый потребитель существующих событий без изменения источника.

Сложности EDA

Eventual consistency. Система не гарантирует мгновенной согласованности. После публикации события потребители обработают его через какое-то время. Это требует переосмысления UX и бизнес-логики.

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

Идемпотентность. Потребитель должен корректно обработать одно событие несколько раз — at-least-once delivery гарантирует доставку, но не единственность.

Observability. Отследить обработку запроса через цепочку событий и потребителей сложнее, чем синхронный вызов. Требует correlation ID в каждом событии и distributed tracing.

Когда применять EDA

EDA хорошо подходит для: интеграции нескольких систем или микросервисов, обработки потоков данных в реальном времени (аналитика, логи, IoT), рабочих процессов с асинхронными шагами (обработка заказа, транскодирование видео), систем с переменной нагрузкой, где нужно сглаживать пики.

EDA не нужна там, где достаточно прямого синхронного вызова и не предвидится сложная интеграция. Не стоит усложнять простые CRUD-операции асинхронными событиями без реальной необходимости.

Apache Kafka как стандарт для EDA

Kafka — распределённый журнал событий (commit log), изначально разработанный в LinkedIn. Хранит события на диске с настраиваемым retention. Обеспечивает высокую пропускную способность (миллионы сообщений в секунду) за счёт последовательной записи и репликации. Потребители читают независимо и могут перематывать историю назад — уникальная возможность для аудита и отладки.

Частые вопросы

  • Чем event-driven отличается от обычного message queue?

    Message queue (RabbitMQ) — задача обрабатывается одним потребителем и удаляется из очереди. Event log (Kafka) — событие сохраняется и может быть прочитано несколькими независимыми потребителями. EDA часто использует оба подхода в зависимости от сценария.

  • Как гарантировать обработку каждого события хотя бы один раз?

    At-least-once delivery: брокер повторяет доставку до подтверждения от потребителя. Потребитель должен быть идемпотентным — повторная обработка одного события не должна давать побочных эффектов. Для этого используют уникальный идентификатор события и запись обработанных ID.

  • Что выбрать: Kafka или RabbitMQ?

    Kafka — для высоких объёмов, долгосрочного хранения событий и их воспроизведения, потоковой обработки. RabbitMQ — для сложной маршрутизации сообщений, задач с различными приоритетами, классического message broker-паттерна. Для большинства микросервисных систем с событийной моделью Kafka стал стандартом.

Не хватает деталей?

Напишите, что уточнить по теме «event driven архитектура» — это помогает улучшать материал и подсказывает, какие термины добавить дальше. Email необязателен: укажите, если хотите ответ только для вас (мы не шлём рассылки).

Поделиться