Руководство для начинающих по архитектуре событий в микросервисах

Что такое архитектура событий и почему это важно сейчас

Event Driven Architecture (EDA) стала краеугольным камнем современного дизайна микросервисов. По мере того, как организации масштабируют свои распределенные системы, традиционная модель синхронного ответа на запросы вводит тесную связь, каскадные сбои и ограниченную пропускную способность. EDA решает эти проблемы, переключая связь на асинхронные события - службы публикуют факты о том, что произошло, и другие службы реагируют независимо. Это руководство охватывает основные концепции, шаблоны, технологии и практические шаги, необходимые для создания масштабируемых, устойчивых и поддерживаемых событий микросервисов.

Основные принципы архитектуры событий

Асинхронная коммуникация

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

Свободное соединение

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

Событие Неизменяемость

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

Состоятельная последовательность

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

Ключевые компоненты системы, управляемой событием

Продюсеры событий

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

События Потребители

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

Брокер сообщений / Автобус событий

Брокер находится между производителями и потребителями, управляя маршрутизацией событий, настойчивостью и доставкой. Он обеспечивает механизм публикации-подписки, который позволяет свободно связываться. Ключевые функции, которые нужно искать, включают:

Темы и каналы

События организованы в темы или каналы. Тематические группы, связанные с событиями - например, "order events" или "payment events". Гранулярность тем - это дизайнерское решение: слишком грубые и потребители получают много нерелевантных событий; слишком тонкие, и у вас есть взрыв тем. Общий подход - это отображение тем в ограниченные контексты или агрегаты доменов.

Когда использовать архитектуру событий против запроса-ответа

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

Избегайте EDA, когда:

Многие системы используют гибридный подход: синхронные API для простых операций CRUD и событийных шаблонов для сложных рабочих процессов, интеграций и функций в реальном времени.

Общие события Движимые архитектурными шаблонами

Уведомление о событии

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

Передача государства, осуществляющего мероприятия

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

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

Состояние системы выводится из журнала событий, а не хранится непосредственно. Каждое изменение состояния добавляется как неизменное событие. Текущее состояние реконструируется путем повторения событий (возможно, с помощью снимков для производительности). Истоки событий обеспечивают идеальную проверяемость, временные запросы и возможность перестраивать модели чтения. Это добавляет сложность вокруг эволюции схемы и требует тщательного проектирования событий. Он естественным образом сочетается с CQRS.

CQRS (Command Query Responsibility Segregation) — сегрегация ответственности

CQRS разделяет модели записи (команды) и чтения (запросы). Команды генерируют события, которые потребляются для обновления моделей чтения. Это позволяет оптимизировать каждую модель независимо, например, используя высоко нормализованный магазин записи и денормализованный магазин чтения, оптимизированный для конкретных запросов. CQRS часто используется с поиском событий, но также может использоваться независимо.

Сага шаблон

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

Саги необходимы для обеспечения согласованности данных в распределенных, в конечном итоге согласованных системах.

Популярные технологии для событийной архитектуры

Апач Кафка

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

Кролик MQ

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

Amazon EventBridge

EventBridge - это бессерверная шина событий, которая соединяет сервисы AWS, приложения SaaS и пользовательские приложения. Он предлагает реестр схем, фильтрацию событий, преобразование и нативную интеграцию с функциями Lambda и Step. EventBridge не требует автоматического управления инфраструктурой и масштабирования. Он идеально подходит для архитектур, ориентированных на AWS, но может иметь более высокие затраты на событие при очень больших объемах.

Azure Event Hubs и сервисный автобус

Azure Event Hubs - это платформа для потоковой передачи больших данных для приема телеметрии, похожая на Kafka. Azure Service Bus - полностью управляемый бизнес-брокер сообщений для публикации-подписки и очередей, с такими функциями, как транзакции, обнаружение дубликатов и мертвая буква. Оба глубоко интегрируются с экосистемой Azure.

Google Cloud Pub/Sub

Pub/Sub - это полностью управляемый глобальный сервис обмена сообщениями с доставкой не реже одного раза и автоматическим масштабированием. Он поддерживает доставку push-and- pull и интегрируется с сервисами Google Cloud. Это надежный выбор для архитектур на основе GCP.

Проектирование событий для вашей системы

Событие Granularity

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

Конвенция об именовании событий

Используйте прошедшее время, чтобы указать на то, что уже произошло. Включите контекст домена, чтобы избежать двусмысленности: «Billing.InvoiceGenerated» против «Shipping.InvoiceGenerated». Последовательность в организации облегчает понимание и обслуживание системы.

Проектирование Schema Design

Схема событий должна включать стандартные метаданные:

Полезная нагрузка должна содержать все данные, необходимые потребителям для обработки события без дополнительных запросов (передача состояния, связанного с событием). Используйте реестр схем для хранения и обеспечения соблюдения схем. Выберите формат сериализации: JSON является читаемым человеком, в то время как Avro или Protobuf предлагают лучшую производительность и поддержку эволюции схем.

Эволюция схемы

События - это контракты, и они изменятся. План эволюции с самого начала:

Внедрение лучших практик

Императивность

Потребители должны безопасно обрабатывать дублирующие события. Стратегии включают:

Обработка ошибок и повторы

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

Заказ мероприятия

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

Мониторинг и наблюдаемость

Отслеживайте ключевые показатели: скорость публикации событий, задержка потребителя, время обработки, скорость ошибок, глубина очереди в мертвой букве. Используйте распределенное отслеживание с идентификаторами корреляции для отслеживания событий в службах. Настройте оповещения о аномалиях, таких как внезапное падение объема событий или увеличение задержки потребителей. Создайте панели инструментов, которые обеспечивают в режиме реального времени представление о состоянии потока событий.

Безопасность

Мероприятия могут содержать конфиденциальные данные. Внедрить аутентификацию и авторизацию для публикации и подписки. Шифровать события в пути (TLS) и в покое. Используйте сегментацию сети для изоляции брокера. Проверять доступ к потокам событий и внедрять политики хранения данных в соответствии с требованиями соответствия. Рассмотрите возможность шифрования чувствительных полей в полезных нагрузках событий.

Общие вызовы и решения

Отладка распределенных потоков

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

События Storms

Буря событий возникает, когда события вызывают каскадные события, потенциально создавая бесконечные петли или подавляя систему.

Тестирование асинхронных систем

Тестирование систем, управляемых событиями, требует различных подходов:

Начало работы с Event Driven Architecture

1.Определите свои события

Запустите семинары по штурму событий с экспертами домена. Определите события, которые представляют собой значимые бизнес-встречи. Начните с небольшого, четко определенного подмножества - например, «Заказ размещен» и «Полученный платеж». Документируйте каждое событие: цель, полезная нагрузка, производитель и потребители.

2 Выберите своего брокера

Для новых команд EDA рассмотрите управляемый сервис, такой как Amazon EventBridge или Google Cloud Pub/Sub, чтобы уменьшить операционные накладные расходы. Если вам нужна высокая пропускная способность и повторение событий, выберите Kafka, несмотря на его сложность. Для более простых вариантов использования RabbitMQ является прочной отправной точкой. Рассмотрите существующий опыт и инфраструктуру вашей команды.

3.Проектирование схем событий

Создать стандартные поля метаданных. Проектировать полезные нагрузки с использованием переноса состояний, переносимых событиями. Выбрать формат сериализации (JSON для простоты, Avro/Protobuf для производства). Создать реестр схем, если это возможно. Установить соглашения об именах и политику эволюции.

4. Осуществление и испытание

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

5. Переименовать и задокументировать

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

Реальные случаи использования

Обработка заказов электронной коммерции

Когда клиент размещает заказ, событие «OrderPlaced» запускает несколько независимых сервисов: резервирование запасов, обработка платежей, планирование доставки и уведомление. Если оплата не удается, компенсирующее событие выпускает инвентарь. Каждая услуга масштабируется независимо на основе собственной нагрузки. Журнал событий предоставляет полную историю заказов для поддержки клиентов и аналитики.

Аналитика в реальном времени и обнаружение мошенничества

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

IoT-сенсор для приема данных

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

Заключение

Event Driven Architecture - это мощная парадигма для создания современных микросервисов, которые являются масштабируемыми, устойчивыми и поддерживающими. Обнимая асинхронную связь, свободную связь и неизменность событий, вы можете избежать подводных камней синхронных распределенных систем. Ключ заключается в том, чтобы начать с малого, выбрать правильную технологию на основе ваших требований и инвестировать в идемпотентность, мониторинг и управление схемами с самого начала. Используйте шаблоны и практики, изложенные здесь, для разработки событийных систем, которые могут расти с вашим бизнесом. Для дополнительного руководства по шаблонам микросервисов посетите Microservices.io и исследуйте спецификацию CloudEvents для совместимых форматов событий.