Понимание архитектурных шаблонов, основанных на событиях: Pub / Sub, Cqrs и многое другое

Архитектура, управляемая событиями (EDA) стала основополагающей парадигмой проектирования для построения распределенных, масштабируемых и отзывчивых систем. Вместо того, чтобы полагаться на тесную связь между компонентами посредством прямых вызовов методов или удаленных вызовов процедур, EDA переносит связь на производство, обнаружение и потребление событий. Событие - это значимое изменение состояния - то, что произошло, что другие части системы могут заботиться о. Это разделение позволяет каждой службе развиваться независимо, масштабироваться самостоятельно и реагировать на изменения по мере их возникновения. Понимание основных моделей EDA - таких как Публикация / Подписка (Pub / Sub), Сегрегация ответственности командных запросов (CQRS) и Искажение событий - имеет важное значение для любого разработчика или архитектора, стремящегося создать современные облачные приложения, которые могут обрабатывать потоки данных в реальном времени и непредсказуемые модели нагрузки.

Что такое событийно-управляемая архитектура?

По своей сути, EDA рассматривает события как первоклассных граждан. Событие - это неизменная запись того, что произошло в прошлом - например, OrderPlaced , UserRegistered или PaymentFailed . Компоненты, известные как производители событий, генерируют эти события, не зная, какие компоненты будут их потреблять. Потребители событий подписываются на конкретные типы событий и реагируют соответствующим образом. Брокер событий, такой как Apache Kafka, RabbitMQ или AWS EventBridge, сидит между производителями и потребителями, обеспечивая надежную доставку, настойчивость и порядок семантики, когда это необходимо.

Эта архитектура контрастирует с традиционными моделями синхронного запроса-ответа, где сервис напрямую вызывает другую услугу и ждет ответа. Синхронная связь создает плотную связь: если служба нисходящего потока медленная или недоступная, абонент блокируется. С EDA производители запускают события и немедленно продолжают свою работу. Потребители обрабатывают события асинхронно, часто с помощью собственной политики масштабирования. Эта модель не только повышает устойчивость системы, но и позволяет в реальном времени передавать потоки, проверяемость и возможность добавлять новых потребителей без изменения существующего кода.

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

Основные шаблоны в Event-Driven архитектуре

Публикация/подписка (Pub/Sub)

Паттерн Pub/Subscribe (Pub/Sub) является самым простым и широко распространенным шаблоном EDA. В этой модели издатели выделяют события на тему или канал. Абоненты регистрируют интерес к этим темам и получают все опубликованные им события. Брокер обрабатывает вентиляцию, гарантии доставки и фильтрацию. Издатели и подписчики не знают друг друга — в этом суть свободной связи.

Например, рассмотрим платформу электронной коммерции. Когда клиент размещает заказ, служба заказа публикует событие OrderPlaced на тему «заказов». Несколько подписчиков подбирают это событие:

Каждый абонент обрабатывает событие самостоятельно и в своем темпе. Если служба уведомлений медленная, это не влияет на службу заказа или службу инвентаризации. Этот шаблон, естественно, поддерживает масштабирование; вы можете добавить больше экземпляров службы инвентаризации для обработки повышенной нагрузки, не касаясь других компонентов.

Популярные инструменты для реализации Pub/Sub включают Apache Kafka, который обеспечивает высокую пропускную способность, постоянные и воспроизводимые потоки событий; RabbitMQ с его маршрутизацией и обменами темами; и облачные сервисы, такие как AWS EventBridge, который предлагает реестр схем и фильтрацию. Выбор правильного брокера зависит от вашей долговечности, заказа и требований к пропускной способности.

Разделение ответственности командных запросов (CQRS)

Разделение ответственности командных запросов (CQRS) - это шаблон, который отделяет операции записи (команды) от операций чтения (запросы) в разные модели. В традиционных системах CRUD одна и та же модель данных используется как для обновлений, так и для считывания, что может привести к проблемам производительности, когда рабочая нагрузка несбалансирована - например, сложный путь записи, который также должен обслуживать запросы чтения, оптимизированные для другой схемы.

В системе на основе CQRS команда, такая как PlaceOrder, запускает модель записи, которая проверяет бизнес-правила и производит событие (например, OrderCreated. Это событие обновляет базу данных на стороне записи. Между тем, отдельная модель чтения — часто денормализованная, оптимизированная под запросы база данных — слушает одно и то же событие и обновляет свои собственные таблицы. Запросы попадают в модель чтения, которая может быть масштабирована независимо или даже использовать совершенно другую технологию (например, Elasticsearch для поиска, Redis для кэширования). Модель записи и модель чтения в конечном итоге согласованы.

Преимущества CQRS включают в себя:

Однако CQRS добавляет сложность, поскольку он вносит возможную согласованность и часто требует синхронизации, управляемой событиями, между двумя сторонами. Он естественным образом сочетается с Event Sourcing, где сторона записи хранит последовательность событий, а не снимок текущего состояния. Статья Мартина Фаулера о CQRS является отличным ресурсом для понимания компромиссов шаблона.

Источник событий

Источник событий - это шаблон, в котором изменения состояния хранятся в виде хронологической последовательности событий, а не в виде снимка текущего состояния. Вместо того, чтобы перезаписывать запись в базе данных, каждая мутация генерирует новое событие, добавленное к журналу событий. Текущее состояние может быть получено путем повторения всех событий с самого начала - или с помощью снимков с интервалами для ускорения восстановления.

Event Sourceing предоставляет несколько мощных преимуществ:

Основной компромисс - это увеличение объема и сложности. Запрос непосредственно в магазине событий часто неэффективен, поэтому вы обычно создаете модели чтения (Проекции), которые материализуют взгляды. Искажение событий распространено в таких областях, как финансовый учет, банковское дело и совместное редактирование документов, где каждое изменение должно быть записано.

Event Streaming (Стриминг)

Потоковое событие рассматривает события как непрерывный, неограниченный поток данных. Этот паттерн используется для анализа, мониторинга и интеграции данных в реальном времени в масштабе. В потоковом событии события поступают от нескольких производителей и обрабатываются в режиме реального времени потоковыми процессорами, которые фильтруют, агрегируют и преобразуют данные. Обработанные результаты могут храниться, отправляться в другой поток или использоваться для запуска действий по потоку.

Apache Kafka является фактическим стандартом для потокового вещания событий. Он хранит события в неизменяемых журналах через разделы для отказоустойчивости и горизонтальной масштабируемости. Рамки обработки потоков, такие как Kafka Streams, Apache Flink и Spark Streaming, позволяют обрабатывать сложные события с помощью семантики ровно один раз. Например, компания, предоставляющая услуги совместного использования поездок, может передавать местоположения GPS для расчета ценообразования, обнаружения доступности драйверов и обновления ETA-рейдеров - все в режиме реального времени.

Потоковое вещание событий также является основой для сетки данных и событийных микросервисов, где вы хотите отделить производителей данных от потребителей на уровне инфраструктуры данных.

Другие важные шаблоны и шаблоны в сочетании

Сага шаблон

В распределенных транзакциях, особенно в микросервисах, шаблон Saga управляет многоступенчатыми рабочими процессами. Каждый шаг в саге публикует событие или выполняет действие. Если шаг не удается, сага запускает компенсирующие события, чтобы откатить предыдущие шаги. Саги могут быть организованы (центральный координатор сообщает каждой службе, что делать) или поставлены (каждая служба слушает события и решает сама). EDA позволяет хореографировать саги: служба излучает событие, следующая служба делает свою часть, и если она не удается, она излучает событие отказа, которое вызывает откаты. Этот шаблон необходим для поддержания согласованности данных без распределенной блокировки.

Реактивное программирование

Хотя реактивное программирование не является строго архитектурным шаблоном, оно хорошо согласуется с EDA. Такие фреймворки, как RxJS, Reactor и Akka Streams, позволяют разработчикам составлять асинхронную и основанную на событиях логику с использованием наблюдаемых последовательностей. Это особенно полезно для клиентов (например, обновления пользовательского интерфейса в реальном времени) и в серверных потоках, где вам нужно обрабатывать большие объемы событий с обратным давлением.

Сотрудничество в рамках мероприятия

Сотрудничество событий — это шаблон, в котором службы разделяют общую модель событий и общаются исключительно через события. Каждая служба поддерживает свою собственную логику домена и проецирует события в свои собственные хранилища данных. Не существует прямых вызовов API-интерфейса обслуживания. Этот шаблон максимизирует автономность и часто используется в дизайне, ориентированном на домен, с ограниченными контекстами. Основная проблема заключается в версии: когда схема событий изменяется, все потребители должны обновляться или терпеть эволюцию схемы (например, используя Avro или Protobuf с регистрами схем).

Выбираем правильный шаблон

Выбор схемы EDA зависит от ваших конкретных требований.

Преимущества Event-Driven Architecture

Помимо непосредственных преимуществ разъединения и масштабируемости, EDA предоставляет ряд операционных и бизнес-преимуществ:

Вызовы и лучшие практики

EDA мощная, но не без подводных камней. Общие проблемы включают:

Лучшие практики включают в себя: сначала начните с простого — используйте Pub / Sub и добавьте CQRS или Event Sourcing только тогда, когда это оправдано; инвестируйте в хороший реестр схем; обеспечивайте очереди мертвой буквы для неудачных событий; и регулярно моделируйте сбои, чтобы обеспечить работу вашей саги, компенсирующей логику.

Заключение

Модели архитектуры, ориентированные на события - от базового Pub / Sub до более специализированных CQRS, Event Sourcing и потоковой передачи событий - предлагают надежный инструментарий для построения систем, которые масштабируемы, устойчивы и отзывчивы. Благодаря разъединению производителей и потребителей EDA позволяет командам итерировать независимо, изящно обрабатывать непредсказуемые нагрузки и разблокировать возможности в режиме реального времени. Однако она также вводит сложность в согласованность, отладку и управление схемами. Команды, которые инвестируют в понимание компромиссов и внедряют лучшие практики, найдут EDA незаменимым шаблоном для современного проектирования распределенной системы. Поскольку индустрия движется к событиям, управление этими шаблонами больше не является обязательным - это основная компетенция для архитекторов и разработчиков, создающих следующее поколение облачных приложений.