Должны ли сервисы напрямую взаимодействовать друг с другом в микросервисной архитектуре?

10

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

Должны ли эти службы общаться напрямую друг с другом? Если это так, разве это не объединит их, что противоречит концепции микросервисов?

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

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

cod3min3
источник
Если вещи полностью расцеплены, то это совершенно разные продукты. Таким образом, пользователь должен будет войти в Contoso Login, затем Contoso Login скажет: «Вы вошли в систему!» ... и затем они перейдут в хранилище чувствительных данных Contoso, отметьте поле «Да, я вошел в систему». «... затем скопируйте и вставьте данные из этого в процессор данных Contoso ...
user253751

Ответы:

15

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

В конце концов, у вас будет приложение для микросервисов, которое будет медленнее, чем альтернативное монолитное приложение, но с почти такими же проблемами!

Я должен не согласиться с @ Робертом Харви

На практике, однако, один или несколько ваших микросервисов (возможно, все они) будут общаться с некоторым центральным хранилищем данных, таким как база данных SQL.

Интеграция базы данных известного антипаттерна

Гораздо лучшим решением является использование шаблона публикации-подписки для того, чтобы сделать связь между вашими сервисами асинхронной:

введите описание изображения здесь

Пожалуйста, взгляните на CQRS / ES способ реализации этого метода общения, Грег Янг и другие ребята предлагают множество хороших видео по этой теме. Просто Google для ключевого слова "CQRS / ES". При таком подходе каждый сервис становится издателем и подписчиком одновременно, что позволяет сервисам быть гораздо менее связанными.

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

IlliakaillI
источник
2
Ну, во-первых, я нигде не слышал термин «база данных интеграции», кроме Фаулера. Не принимайте что-либо как евангелие только потому, что один парень сказал это. Во-вторых, у вас недостаточно информации, чтобы назвать то, что я описал, «интеграционной базой данных». В-третьих, Фаулер на самом деле называет такие базы данных полезными при правильных обстоятельствах, в той же статье, на которую вы ссылались. Мне нравится идея шины событий, хотя я не понимаю, чем она отличается от вызова обычного API микросервиса, если только вы не можете повысить эффективность.
Роберт Харви
Спасибо, Роберт, я связал статью Фаулера, чтобы лучше проиллюстрировать идею, а не спорить с авторитетом. То, как вы описали этот подход, очень похоже на интеграцию с базой данных. Если это не так - это совсем не очевидно. Что касается правильных обстоятельств - я думаю, что интеграция микросервисов через базу данных не очень хорошая идея, поскольку она подталкивает нас к монолитной архитектуре.
IlliakaillI
1
Конечно: каждый микросервис будет общаться со своей отдельной базой данных или с таблицами в той же базе данных, которые не связаны с таблицами других служб. Таким образом, сервисы никогда не обмениваются информацией через базу данных, что означает, что вы можете легко масштабировать по горизонтали, и узких мест будет гораздо меньше. И поскольку они не используют одни и те же таблицы - изменения в одной части приложения будут менее вероятно влиять на другие части.
IlliakaillI
1
Вы не можете категорически утверждать, что это абсолют. Возможно, в одной и той же базе данных есть две службы, которым нужна одна и та же информация, они нужны только время от времени, проблем с масштабированием для доступа к ней нет, в любом случае эти две службы уже обращаются к базе данных для других целей, так что стоит служебная шина или конечная точка API просто для достижения этого было бы смешно.
Роберт Харви
1
Но для достижения бизнес-ценности вы хотите объединить данные - «покажите мне все канализационные системы, у которых будет недостаточно места для хранения, учитывая следующие радиолокационные данные о поступающем дожде, и раскрасьте эту карту муниципалитетов, используя результат». Если вы разбиваете все свои данные на сервисы, это просто означает, что вы можете объединить данные только позже. Если вы запрещаете сервисам общаться друг с другом, вы просто принуждаете себя переместить все данные к какому-либо клиенту и присоединить данные там. Вы ХОТИТЕ связать данные где-нибудь, так как это то, что в итоге дает ценность приложения.
RemcoGerlich
8

Вы получите много очень хороших идей, прочитав, что Udi Dahan говорит о SOA .

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

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

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

В частности, что касается композиции пользовательского интерфейса, статья Мауро Сервиенти о композиции пользовательского интерфейса является хорошей отправной точкой. Смотрите также видео Уди, доступное здесь .

Должны ли эти службы общаться напрямую друг с другом? Если это так, разве это не объединит их, что противоречит концепции микросервисов?

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

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

VoiceOfUnreason
источник
7

Это зависит от того, что вы подразумеваете под «напрямую».

В соответствии с архитектурой микросервисов совершенно нормально иметь микросервисы, которые вызывают другие микросервисы, либо на вашем собственном сервере, либо даже на внешних серверах, через некоторый интерфейс, например REST.

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

Майк Накис
источник
это не хорошо и будет иметь плохие последствия. Смотрите мой ответ для более подробной информации.
IlliakaillI
@IlliakaillI Я говорю, что это хорошо "в соответствии с архитектурой микросервисов". Я не утверждаю, что архитектура микросервисов свободна от последствий или что в нее нельзя внести никаких улучшений. Вопрос здесь: «Х книгой или нет?» и правильный ответ заключается в том, что, учитывая правильное определение X, оно написано в книге.
Майк Накис
Есть ли «справочник», в котором рассказывается, как построить настоящую «архитектуру микросервисов»? Микросервисы стали модным словом в наше время, и многие люди писали книги о том, как строить монолиты на вершине REST. Просто посмотрите на эту первую диаграмму в моем ответе, нет смысла строить систему таким образом. Если вы делаете по какой-то странной причине - вы определенно делаете это неправильно. Вам лучше пойти с монолитом вместо этого. Если вы подтверждаете свой выбор дизайна, слепо ссылаясь на некоторые книги (приводя аргументы от авторитета), это неправильный подход к разработке программного обеспечения.
IlliakaillI
5

Должны ли эти службы общаться напрямую друг с другом? Если это так, разве это не объединит их, что противоречит концепции микросервисов?

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

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

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

Роберт Харви
источник
3
«Интеграционная база данных» является известным антипаттерном, см. Мой ответ для более подробной информации.
IlliakaillI
2

Кажется, что, говоря о SOA и архитектуре в целом, люди оказываются вовлеченными в семантику и жаргон. Что делает услугу «микро»? В конечном счете, это некоторый набор характеристик, которые в любой используемой вами «системе оценки» явно не делают сервис «немикро». Что сказал верховный суд о непристойности? «Я узнаю это, когда увижу».

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

Мерцающая точка ком
источник
1

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

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

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

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


(Кроме того, поездки до клиента, вероятно, обходятся дороже, чем от ваших микросервисов друг к другу.)


Например, если вы посмотрите на направление, используемое GraphQL, то обнаружите, что клиенты выдают напрямую соответствующие запросы конечной точке, которая может быть или не быть реализована как набор микросервисов. Поскольку архитектура микросервисов скрыта за GraphQL, это упрощает ее реорганизацию и делает ее более удобной для клиента. См., Например, https://stackoverflow.com/a/38079681/471129 .

Эрик Эйдт
источник
1

Основная цель микроуслуг - сделать ваше приложение слабо связанным. Поэтому службы не могут звонить друг другу. В противном случае он будет тесно связан. Но что мы будем делать, если у нас есть две службы, которые должны обмениваться данными? Ответ - Message Broker. Таким образом, служба, которая получает данные от клиента, может обмениваться данными с центральным брокером сообщений, а затем службы должны использовать эти данные, чтобы использовать их, преобразовывать и помещать в свое собственное хранилище данных. Я рекомендую Kafka, потому что вы можете объединять данные из разных тем на лету с Kafka Stream. PS. Лучше разделить ваши микро-услуги по функциям.

Пануват Анаватмонгхон
источник