Много-много-много ассоциаций в микросервисах

13

У меня сейчас два микросервиса. Мы им позвоним Aи B.

База данных под микросервисом Aимеет следующую таблицу:

A
|-- users

База данных под микросервисом Bимеет следующую таблицу:

B
|-- trackers

Требования утверждают, что usersи trackersимеют отношение многие ко многим.

Я не уверен, как правильно справиться с этим в архитектуре микросервисов.

Я мог видеть, что это работает одним из трех способов:

  1. user_trackersТаблица добавляется к microservice A. Это действует подобно таблице соединения, содержащей «внешние ключи» для usersи trackers.
  2. ownersТаблица добавляется к microservice B. Эта таблица действует аналогично таблице полиморфного соединения. Это позволило бы любой службе создать ассоциацию с трекером. Это может выглядеть примерно так: B |-- trackers |-- owners |-- owner_id |-- owner_type |-- tracker_id
  3. Храните записи для usersи trackersв каждом microservice. Держите их в синхронизации с какой-то системой pubsub.

Изначально я собирался пойти с вариантом 2, потому что мне понравилось, что он сохранил границы транзакций. Я могу создать трекер и связать его с чем-то атомарно. Тем не менее, это кажется вне сферы применения микросервиса B. Почему микросервис должен Bзаботиться о том, что микросервис Aхочет создать ассоциацию?

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

anthonator
источник

Ответы:

12

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

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

Во-вторых, вы, вероятно, недостаточно хорошо проработали свой домен. Какая концепция представлена ​​в usersтаблице? Это registered user, со всей информацией и поведением, необходимыми для регистрации? Вы уверены, что это правильная концепция для общения trackers(с чем бы это ни было)? Так что, если я правильно понял, ваш вариант 2 именно об этом: введение ownerконцепции, которая намного ближе к вашей области. Если это действительно так, я тоже за вариант 2.

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

Это все о границах. Я думаю, вы хотите сформировать микроуслуги вокруг сущностей. Вот где SOA потерпела неудачу с многоуровневой сервисной архитектурой . Лучшим подходом является создание служб, которые представляют некоторую бизнес-функцию, поэтому они инкапсулируют как данные, так и поведение. С более практической точки зрения речь идет о создании сервисов на основе бизнес-процессов или сценариев использования. Например, у вас может быть один сервис для регистрации пользователей. Он содержит данные пользователя и поведение, необходимое для регистрации пользователя. Таким образом, концепция userформируется естественным образом и относится только к услуге А. И это подводит меня к следующему пункту: другой способ думать об услугах - это ограниченный контекст . Хорошей практикой является согласование сервисов и ограниченных контекстов.

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

Будьте предельно осторожны с вариантом 3. Если вы копируете данные, функциональность следует. Это приводит к жесткой связи. И не используйте термин CQRS , речь идет не о синхронизации данных между сервисами через события.

Западло
источник
Мне нравится термин «распределенный монолит», но то, как он определен в приведенной вами ссылке, похоже, не имеет прямого отношения к данному вопросу. То, как я думаю, вы используете его, связано со связью между сервисами, а статья посвящена бинарным зависимостям. Я думаю, что вы используете превосходно, но я изо всех сил пытаюсь найти ссылку, которая четко определяет это таким образом.
JimmyJames
Я всегда включал чат-сервисы в категорию «распределенный монолит», что не очень распространено.
Западло
6

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

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

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

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

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

JimmyJames
источник
0

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

Знак
источник
0

Вопрос: Почему ваши данные разделены по Datatables?

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

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

Кристиан Зауэр
источник
Это часть религии микросервисов, что каждая служба нуждается в полной автономии. Томас Эрл описывает это как один из принципов ориентации на обслуживание в «Принципах проектирования услуг» c. 2008.
JimmyJames
@JimmyJames Как кто-то, кто пишет мс-архитектуру сам: Есть много споров по вопросу о том, какой должна быть мс. В этом случае размер может даже не иметь значения, поскольку службы могут быть разделены неправильно - например, не разрезать по таблицам, разрезать по бизнес-доменам.
Кристиан Зауэр
Правильно. Проблема в том, что сейчас существует огромный культ груза вокруг микросервисов. Я вижу, что многие люди внедряют микросервисы, потому что это то, что делают крутые дети, а не рассматривают или понимают компромиссы. Например, я чувствую, что многие люди думают, что автономия MS связана с технологиями и «облаком». Я считаю, что это скорее решение организационной проблемы. Разыменование торгового указателя для сетевого ввода-вывода чрезвычайно дорого. Вы не можете просто применить это бездумно и ожидать, что все пойдет хорошо.
JimmyJames
@JimmyJames Я думаю, что это может быть и о технологиях, особенно когда технологии certian хорошо подходят для одних областей, но не для других. Мы используем C # и Python для наших MS. Частично это связано с организационными проблемами («Я запрограммировал c # на 20 лет, мне не нужно изучать новомодные нетипизированные языки!»). - но также из-за характера нашей системы. Части науки о данных лучше всего сделаны на python, а некоторые инфраструктурные и веб-задачи лучше всего выполняются на C #.
Кристиан Зауэр
Конечно, это довольно веская причина для этого. Проблема, которую я вижу, состоит в том, что люди захотят разделить каждый сервис на отдельный узел просто потому, что «мы делаем микросервисы», даже если все написано с одним и тем же кодом на одной и той же платформе и существует множество зависимостей между сервисами. В этом случае микросервисам нет особой пользы, и вы добавили целый ряд новых проблем.
JimmyJames