Как реализовать хореографию на практике
В прошлом посте мы разобрались что такое паттерн "Хореография", его характеристики, когда его можно использовать. Теперь посмотрим, как его реализовать.
В теории всё красиво — сервисы публикуют и слушают события, система масштабируется, нет дирижёра…
Но как это реализовать на практике?
Основа архитектуры
Сердце паттерна хореографии - это асинхронный обмен сообщениями(событиями) между сервисами. В процессе обработки запросов или сообщений они публикуют события, возникшие в процессе, в шину данных (Event Bus). Другие сервисы, заинтересованные в конкретных событиях, подписываются на них.
Самые популярные технологии обмена сообщениями:
- Kafka — распределенная платформа обмена сообщениями и обработки потоковых данных в режиме реального времени, которая позволяет обрабатывать большое количество сообщений и дает высокую надежность.
- RabbitMQ — брокер сообщений с поддержкой различных топологий очередей и возможностью гибкой настройки маршрутизации.
- Облачные MQ/Brokers
Роль контрактов
Когда сервисы общаются не напрямую, а через события, им нужен четкий и стабильный "язык" для общения. Этот язык — контракт события (Event Schema).
Контракт определяет структуру и тип данных события. Например, событие OrderCreated должно всегда содержать orderId, userId и amount. Если один сервис начнет отправлять order_id вместо orderId, другие его не поймут.
Что важно для контрактов:
- Схема событий (Event Schema): Используйте формальные языки описания схем, такие как Apache Avro, Protobuf или JSON Schema. Это позволяет автоматически валидировать события и генерировать код для их сериализации/десериализации.
- Реестр схем (Schema Registry): Это централизованное хранилище всех версий ваших контрактов. Оно гарантирует, что все участники обмена событиями используют совместимые версии сообщений, и помогает управлять их изменениями без поломок.
- Обратная совместимость: При изменении схемы всегда необходимо учитывать обратную совместимость. Добавление опциональных полей — безопасно. Удаление или переименование существующих — нет.
Контракт — это ваш API в мире событий. К его разработке стоит отнестись так же серьезно, как к проектированию REST API.
Обработка ошибок и консистентность
В распределённых системах сбои неизбежны, и хореография требует, чтобы каждый сервис сам управлял возникающими ошибками. Вот несколько ключевых подходов:
Retry-механизмы
В процессе обработки событий часто могут возникнуть ошибки. Некоторые из этих ошибок временные, например потеря соединения с какой-то частью системы. В таких случай добавляют возможность повторной обработки сообщения через определенный интервал времени. Главное требование в этом случае - идемпотентность операции.
Dead Letter Queue (DLQ)
Если событие не удалось обработать даже через несколько попыток, то оно отправляется в особую очередь, для дальнейшего анализа и обработки, часто в ручном режиме.
Идемпотентность
Логика обработки должна быть идемпотентной — повторная обработка того же события не должна приводить к дублированию данных или ошибочным результатам. Часто добавляется уникальный идентификатор каждому событию.
Консистентность
В общем случае, при разработке систем, в которых хореография становится ключевым свойством, руководствуются принципом eventual consistency (конечной согласованности). Этот принцип подразумевает, что данные могут быть временно несогласованными, но со временем система приходит в согласованное состояние. Для управления консистентностью данных в таких случаях используются различные паттерны - Compensating Transaction/Saga Pattern, Transactional Outbox и т.п.
Наблюдаемость (Observability)
Когда бизнес-процесс "размазан" по нескольким сервисам, понять, что пошло не так, когда возникла ошибка, становится очень трудно. Поэтому стоит рассмотреть подключение на ранних этапах разработки инструментов, которые позволят системе быть наблюдаемой (Observable): распределенную трассировку (Distributed tracing), логирование (Logging), метрики (Metrics).
Заключение
Реализация хореографии на практике требует внимания к деталям и правильного выбора инструментов.
Подписывайся на мой канал в telegram