Это пятая статья из серии об архитектуре микросервисов. Эта статья изначально опубликована на https://www.learncsdesign.com

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

База данных на службу

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

Преимущества наличия базы данных для каждой службы

  • Слабо связанный
  • Свободный выбор типов баз данных, таких как RDBMS, такие как MySQL, базы данных с широкими столбцами, такие как Cassandra, базы данных документов, такие как MongoDB, хранилища ключей и значений, такие как Redis, и базы данных графов, такие как Neo4J.

Нужно ли иметь отдельный сервер базы данных для каждой службы? Это не жесткое требование. Давайте посмотрим, что мы можем сделать.

Если вы используете RDMS, то варианты:

  • Частные таблицы для каждой службы. Существует набор таблиц, принадлежащих каждой службе, доступ к которым должен осуществляться только этой службой.
  • Схема для каждой службы. Каждая служба имеет собственную схему базы данных.
  • Сервер базы данных для каждой службы. У каждой службы есть собственный сервер базы данных.

Проблемы с наличием базы данных для каждой службы

  1. Запросы, которые необходимо объединить в нескольких базах данных. Следующие шаблоны данных помогут нам решить эту проблему.
  • Источники событий
  • Состав API
  • Разделение ответственности за запросы команд (CQRS)

2. Транзакции между несколькими базами данных. Чтобы преодолеть эту проблему, у нас есть шаблон Saga.

Теперь давайте рассмотрим различные шаблоны данных.

Поиск событий

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

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

Преимущества источника событий

  1. Его использование решает одну из ключевых проблем архитектуры, управляемой событиями, и позволяет надежно публиковать события при изменении состояния.
  2. В основном это позволяет избежать проблем несоответствия объектно-реляционного импеданса, поскольку он сохраняет события, а не объекты предметной области.
  3. Он обеспечивает 100% надежный журнал аудита всех изменений, внесенных в объект.
  4. Это позволяет реализовать временные запросы, которые определяют состояние объекта в любой момент времени.
  5. Бизнес-логика, основанная на источнике событий, включает в себя слабо связанные сущности, которые обмениваются событиями. Это значительно упрощает переход от монолитного приложения к микросервисной архитектуре.

Недостатки источников событий

  1. Существует кривая обучения, потому что это незнакомый стиль программирования.
  2. Запрашивать хранилище событий сложно, так как для восстановления состояний сущностей требуется типичный запрос. В результате могут возникнуть неэффективные и сложные запросы. Поэтому приложение должно реализовывать запросы с использованием разделения ответственности команд и запросов (CQRS). В свою очередь, это означает, что приложения должны обрабатывать в конечном итоге согласованные данные.

Состав API

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

Преимущества состава API

  1. Это удобный способ запроса данных в микросервисной архитектуре.

Недостатки состава API

  1. Иногда запросы приводили к неэффективному соединению в памяти больших наборов данных.

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

РСУБД часто используется в качестве транзакционной системы записи и базы данных текстового поиска, такой как Elasticsearch или Solr, для запросов текстового поиска. Некоторые приложения синхронизируют базы данных, одновременно записывая их в обе. Другие периодически копируют данные из СУБД в систему текстового поиска. Приложения, построенные на этой архитектуре, используют сильные стороны нескольких баз данных, транзакционные свойства РСУБД и возможности запросов текстовой базы данных. CQRS обобщает такую ​​архитектуру.

Архитектуры микросервисов сталкиваются с тремя распространенными проблемами при реализации запросов.

  1. Данные, разбросанные по нескольким службам, извлекаются с использованием шаблона композиции API, что приводит к дорогостоящему и неэффективному соединению в памяти.
  2. Данные хранятся в формате или в базе данных, которые не поддерживают требуемый запрос службой, которой принадлежат данные.
  3. Разделение ответственности означает, что служба, которой принадлежат данные, не должна нести ответственность за выполнение операций запроса.

Все три проблемы можно решить с помощью шаблона CQRS.

Основная цель CQRS — разделить проблемы. Следовательно, постоянная модель данных разделена на две части: часть команды и часть запроса.

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

Преимущества CQRS

  1. Включите эффективную реализацию запросов в микросервисной архитектуре. Если вы используете шаблон композиции API для реализации запросов, вы можете столкнуться с дорогостоящими и неэффективными объединениями больших наборов данных в памяти. Для этих запросов использование представления CQRS, которое предварительно объединяет данные из двух или более служб, является более эффективным.
  2. Позволяет эффективно выполнять разнообразные запросы. Часто сложно поддерживать все запросы, используя единую постоянную модель данных. В CQRS определяется одно или несколько представлений, которые эффективно реализуют определенные запросы, устраняя ограничение одного хранилища данных.
  3. Делает возможным выполнение запросов в приложении, основанном на источнике событий — CQRS также преодолевает важное ограничение источника событий. Хранилище событий поддерживает только запросы на основе первичных ключей. Шаблон CQRS устраняет это ограничение, определяя одно или несколько представлений агрегатов, которые поддерживаются в актуальном состоянии путем подписки на потоки событий, публикуемые агрегатами источников событий.
  4. Улучшает разделение ответственности — модели предметной области и модели постоянных данных не поддерживают одновременно команды и запросы. CQRS разделяет команды и запросы службы на отдельные модули кода и схему базы данных.

Недостатки CQRS

  1. Более сложная архитектура. Чтобы обновлять представления и запрашивать их, разработчикам необходимо создавать службы на стороне запросов. Приложение может использовать разные типы баз данных, что усложняет работу как для разработчиков, так и для DevOps.
  2. Устранение задержки репликации. Между публикацией события со стороны команды и его обработкой со стороны запроса и обновлением представления возникает задержка.

Узор саги

Используя саги, вы можете поддерживать согласованность данных в микросервисной архитектуре без использования распределенных транзакций. Вы определяете сагу для каждой команды, которая обновляет данные в нескольких службах. Сага — это серия локальных транзакций. Локальные транзакции обновляют данные в рамках одной службы с использованием платформ транзакций ACID.

Саги используют компенсирующие транзакции для отката изменений. Представьте, что n-я транзакция саги не удалась. Предыдущая (n-1)-я транзакция должна быть отменена. В результате будет инициировано всего (n-1) компенсирующих транзакций для отката изменений в обратном порядке.

Координация саг

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

Есть несколько способов структурировать логику координации саги:

Хореография — распределите принятие решений и последовательность между участниками саги. Они общаются в основном путем обмена событиями.

Преимущества хореографических саг

  1. Простота. Когда бизнес-объекты создаются, обновляются или удаляются, службы публикуют события.
  2. Слабая связь — на события подписываются участники, которые не знают друг о друге.

Недостатки саг, основанных на хореографии

  1. Сложнее понять — Хореография распределяет реализацию саги между сервисами.
  2. Циклические зависимости между сервисами. Участники саги подписываются на события друг друга, что часто создает циклические зависимости.
  3. Риск тесной связи. Участники саги должны подписываться на все события, которые их затрагивают.

Оркестровка. Логика координации саги должна быть централизована в классе оркестратора саги. Во время саги оркестратор отправляет участникам командные сообщения, сообщая им, какие операции они должны выполнять.

Преимущества саг на основе оркестровки

  1. Простые зависимости. Циклические зависимости не вводятся.
  2. Меньше взаимосвязей. Службы реализуют API-интерфейсы, вызываемые оркестратором, поэтому ему не нужно знать о событиях, опубликованных участниками саги.
  3. Улучшает разделение задач и упрощает бизнес-логику. В оркестраторе саг локализована логика координации саг. Объекты предметной области ничего не знают о сагах, в которых они участвуют.

Недостатки саг, основанных на оркестровке

  1. Риск централизации слишком большого количества бизнес-логики в оркестраторе. Если вы разрабатываете оркестраторы, которые отвечают исключительно за виртуализацию и не содержат никакой другой бизнес-логики, этой проблемы можно избежать.

Ниже приведены ссылки на сообщения, в которых более подробно объясняется каждый шаблон.

1. Монолитная или микросервисная архитектура

2. Принципы проектирования микросервисов

3. Шаблоны проектирования микросервисов

4. Шаблоны проектирования декомпозиции микросервисов

5. Шаблоны проектирования данных микросервисов

6. Шаблоны проектирования коммуникаций микросервисов

7. Шаблоны интеграции внешних API микросервисов

8. Шаблоны проектирования наблюдаемости микросервисов

9. Шаблоны проектирования обнаружения сервисов микросервисов

10. Шаблоны проектирования сквозных задач микросервисов

11. Шаблоны проектирования безопасности микросервисов

12. Шаблоны проектирования развертывания микросервисов

Если вам понравился пост, не забудьте похлопать. Если вы хотите подключиться, вы можете найти меня в LinkedIn.

Рекомендации

https://microservices.io