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

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

Я хочу создать 2 автономных микросервиса с API для выполнения необходимых действий. Служба A будет заниматься управлением игроками, а служба B - управлением командой.

В Сервисе A я могу, например, обучать игроков, покупать предметы для игроков, настраивать внешний вид игрока и т. Д. В Сервисе B я могу, например, устанавливать тактику команды, нанимать персонал команды, устанавливать внешний вид команды (логотип, цвет) и т. Д.

Я прочитал много статей и тем о микросервисах, и как написано в одной статье: ... самая сложная часть о микросервисе = ваши данные ...

И вот моя проблема. Как и где я должен хранить отношения между игроком и командой (представьте таблицу TeamPlayer как простую таблицу отношений со столбцами player_id, team_id)? Итак, вот мои опасения:

  1. Должна ли быть таблица TeamPlayer частью микросервиса A или B? Или оба микросервиса должны использовать одну и ту же базу данных?
  2. Если это будут автономные базы данных, и если я решу, что микросервис B будет хранить это отношение, как я могу подтвердить, что этот игрок существует? Что, если кто-то прислал мне неправильный идентификатор игрока? Или мне нужно заботиться? Нужно ли мне подтверждать, что проигрыватель существует, или это не проблема микросервиса B? Конечно, microserivce B знает команды, поэтому я могу вернуть ошибку, если указан неправильный идентификатор команды. Я не хочу вызывать микросервис A из микросервиса B, потому что тогда я свяжу их вместе и сделаю зависимость от микросервиса B до микросервиса A.
  3. Если это будут автономные базы данных, как я буду читать данные? Представьте, что в пользовательском интерфейсе мне нужен список имен игроков внутри команды. Microsoervice B знает команду и просто отношения, а микросервис A знает имена. Мне нужно сделать как минимум два звонка для сбора данных?
  4. Если это будет общая база данных, может ли микросервис B напрямую читать некоторые данные о плеере из базы данных? Я могу представить себе ситуацию, когда это не должно быть разрешено из-за некоторых прав доступа и т. Д., Но вся эта бизнес-логика встроена в микросервис A API, который обычно считывает и возвращает данные о плеере.

Как решить эту проблему наилучшим образом? Является ли шлюз API ответом или как это сделать наилучшим образом?

Я надеюсь, что ясно, что меня беспокоит :)


person MarioooCZ    schedule 13.02.2021    source источник


Ответы (2)


В общем, правильные границы для микросервисов не будут так хорошо совпадать с нормализованными таблицами, которые вы бы использовали в монолитном приложении, поддерживаемом реляционной БД с ограничениями внешнего ключа. Вместо этого я советую позволить каждой службе поддерживать свое собственное представление данных, необходимых для выполнения ее задач (я рекомендую механизм, позволяющий службам публиковать долговременные журналы событий для изменений состояния, для которого они контролируют записи). В вашей концепции сервисов A и B, вероятно, есть несколько ограниченных контекстов: вероятно, будет иметь смысл иметь микросервис для каждого ограниченного контекста.

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

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

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

person Levi Ramsey    schedule 15.02.2021
comment
У меня был связанный с этим вопрос о границах микросервисов. Расширяя приведенный выше пример, как бы мы могли реализовать бизнес-функции, к которым не прикреплен объект данных? т.е. это чисто бизнес-функции. Они не читают и не обновляют данные сами по себе, но они достаточно широки, чтобы их можно было назвать отдельной бизнес-функцией и, следовательно, другим микросервисом. - person Andy Dufresne; 06.05.2021
comment
По сути, это саги: они координируют процессы, состоящие из нескольких операций, касающихся нескольких сервисов. Они не не имеют состояния: им все равно нужно управлять тем, где они находятся (потому что в микросервисах вам абсолютно необходимо иметь дело с частичным отказом (включая службу, предоставляющую сагу), а затем (чаще всего) повторять попытку или откат). Это состояние, вероятно, должно быть какой-то сущностью данных (и это дает некоторые дивиденды с точки зрения наблюдаемости, если ничего другого). - person Levi Ramsey; 06.05.2021

Короткий ответ - таблица TeamPlayer должна быть частью микросервиса A и B обоих.

Для объяснения я заимствую фразу из ответа Леви, я советую позволить каждой службе поддерживать свое собственное представление данных. Это правильный способ разработки микросервиса.

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

Надеюсь, этот ответ даст вам четкое и краткое представление о проблеме вашего дизайна.

person Nitin Gaur    schedule 20.02.2021