микросервисы и ограниченные контексты

Ради вопроса, скажем, у меня есть 2 микросервиса.

  • Управление идентификацией
  • Бухгалтерия

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

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

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

Это правильный способ сохранить согласованность данных и обмен ими между контекстами? Каждый раз, когда пользователь создается в микросервисе идентификации, событие «UserCreated» будет публиковаться, и учетная запись или любая другая служба, заинтересованная в этом событии, должна прослушивать и обрабатывать его, добавляя соответствующий агент? То же самое касается обновления информации о пользователе.


person Robert    schedule 09.08.2016    source источник


Ответы (1)


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

Другие варианты:

Общая база данных

Я знаю, что это не одобряется (не зря), но вы всегда можете поделиться схемой базы данных. Например, контекст Identity может писать в пользовательскую таблицу, а контекст Accounting может читать из нее, когда ему нужен AgentId для выставления счета. Компромисс заключается в том, что вы объединяетесь на уровне базы данных и вводите единую точку отказа.

RPC

Вы можете выполнить RPC-вызов другой службы, когда вам понадобится информация. В вашем примере контекст учета будет вызывать контекст управления идентификацией для информации AgentId / User перед выставлением счета. Компромисс с этим подходом снова связан с другой службой. Что вы делаете, когда он недоступен? Вы не можете выставить счет-фактуру.

Домен отчетности

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

person tomliversidge    schedule 09.08.2016
comment
почему в памяти? Когда вы говорите «служба пользовательского интерфейса», в моем примере это означает, что учетная служба будет иметь только AgentId, но при этом не будет ответственности службы пользовательского интерфейса за создание имени и фамилии из идентификатора агента? - person Robert; 09.08.2016
comment
Не обязательно в памяти, при необходимости может сохраняться. Имея отдельный сервис только для представлений пользовательского интерфейса, вы передаете ему все обязанности по агрегированию данных, необходимых для любых представлений. Но только один вариант :) - person tomliversidge; 09.08.2016
comment
На самом деле это очень хорошая идея. Меня просто беспокоит, как служба выставления счетов узнает, действителен ли AgentId, если у нее нет этих данных в своем контексте и она использует службу пользовательского интерфейса для агрегирования. - person Robert; 09.08.2016
comment
Хорошо, как он узнает, действителен ли AgentId, если вы скопировали детали имени в бухгалтерскую службу? Это похоже на другое требование. Я не говорю, что отдельная услуга только для пользовательских интерфейсов - правильное решение для вас, это всего лишь один из вариантов. Возможно, лучше сделать то, что вы предлагаете в своем вопросе, поскольку это проще - person tomliversidge; 09.08.2016
comment
Я бы знал, что издатель событий - это микросервис, у которого есть правильная информация об AgentId, и данные будут сохраняться таким образом в подписывающейся MS, но микросервис пользовательского интерфейса звучит очень хорошо и добавляет дополнительные возможности к моей проблеме. Спасибо! - person Robert; 09.08.2016
comment
@tomliversidge, как ваше второе решение удовлетворяет потребность в согласованности внутри бухгалтерского учета BC в отношении, скажем, AgentId? Например, при создании счета-фактуры, как вы можете гарантировать, что его AgentId действителен? - person guillaume31; 11.08.2016
comment
Понятия не имею, не знаю, каков процесс проверки AgentId - person tomliversidge; 11.08.2016
comment
Под допустимым я имею в виду тот, который в первую очередь существовал в качестве пользователя в Identity BC ... Без этой гарантии вы можете столкнуться с несовершенной службой модели представления, где половина модели представления нигде не может быть найдена. - person guillaume31; 11.08.2016
comment
Если служба отчетов подписалась на события, чтобы создать представление, как вы в итоге потеряете половину? Я не понимаю, как вы попали в такое состояние, извините - person tomliversidge; 11.08.2016
comment
@ guillaume31i думаю, что понимаю, о чем вы сейчас говорите, и обновил ответ - person tomliversidge; 12.08.2016
comment
На самом деле собственная база данных не обязательно означает собственный сервер базы данных: * Частные таблицы для каждой службы (управляемые с помощью явных грантов) на том же сервере базы данных. * Частная схема для каждой службы на одном сервере базы данных. Важно то, что эти таблицы / схемы свободны от FK для схем других служб. В большом проекте рефакторинга подход частных таблиц фактически был бы моим первым выбором на первых итерациях. - person Thomas Ploch; 12.08.2016
comment
Я бы сказал, что RPC - не совсем подходящий термин для описанной концепции. Вы выполняете правильный сервисный вызов, используя некоторый транспорт, но это не является необходимым RPC. Вы действительно получаете некоторую связь со службой контрактом, а не с самой службой, но такая связь сама по себе не является злом. Я бы сказал, что риск не выставить счет, когда служба идентификации не работает, минимален, поскольку, когда служба id не работает, проще говоря, ничего не работает. Кроме того, каждую службу можно сделать избыточной и отказоустойчивой. Дублирование данных - это легко в теории, но слишком часто возникает ошибка, и это трудно исправить. - person Alexey Zimarev; 17.08.2016