С основными плюсами и минусами каждого

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

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

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

Интеграция конечной точки веб-API RESTful

Один микросервис может легко предоставить конечную точку REST для вызова другими микросервисами. Интеграция через конечные точки RESTful обычно реализуется, когда микрослужбе необходимо вызвать другую и получить немедленный (синхронный) ответ.

Вероятно, это первый шаблон интеграции, который приходит на ум разработчикам, когда они начинают думать об интеграции микросервисов из-за простоты реализации. В самом простом сценарии микросервис 1 может просто использовать класс HttpClient для вызова конечной точки GET микросервиса 2.

Если подход конечной точки REST API выбран в качестве основного шаблона интеграции среди множества микрослужб в проекте, разработчики могут рассмотреть возможность создания веб-клиента с использованием инструментов NSwag и сохранения этого клиента в виде общего пакета NuGet в пользовательском репозитории NuGet.

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

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

  • Надежная связь. Клиентский микросервис знает о серверном микросервисе во время компиляции. Что, если сегодня микросервис A вызывает только микросервис B, а завтра ему придется вызывать микросервисы B и C? Разработчикам придется изменить код микросервиса А.
  • Версии API. Изменение интерфейса конечной точки, используемой другими микрослужбами, может привести к критическим изменениям, которых можно избежать с помощью методов управления версиями API. Однако наличие слишком большого количества версий одного и того же API может привести к появлению большого количества избыточного кода в кодовой базе микросервисов.
  • Обработка ошибок на стороне клиента. Каждая клиентская микрослужба, которая вызывает API других микрослужб, должна реализовать логику повторных попыток для неудачных запросов. Также клиентские микросервисы должны хранить информацию о запросах к какому-либо хранилищу, которые не удалось обработать из-за сбоев или недоступности серверного микросервиса.

🔔 Подпишитесь сейчас, чтобы не пропустить мои следующие статьи.

Интеграция RPC/gRPC

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

С архитектурной точки зрения интеграция микросервисов через gRPC ничем не отличается от их интеграции через конечные точки RESTful Web API.

Инфраструктура gRPC, как и конечные точки RESTful Web API, создает тесную связь между микросервисами. Кроме того, в систему можно легко внести критические изменения, изменив контракт, определенный в файле .proto, и своевременно не обновив клиент.

Подобно подходу конечной точки веб-API RESTful, gRPC хорошо подходит для случаев, когда клиент, инициирующий запрос, должен ждать ответа. Однако gRPC обычно обеспечивает меньшую задержку и высокую пропускную способность, чем подход конечных точек веб-API RESTful, благодаря используемому протоколу Protobuf.

Интеграция обмена сообщениями

В отличие от конечных точек веб-API RESTful или интеграции gRPC, шаблон обмена сообщениями позволяет микрослужбам взаимодействовать друг с другом опосредованно. Связь проходит через компонент шины сообщений, который действует как посредник.

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

Микросервис 1 будет ждать только ответа от служебной шины о том, что сообщение было успешно отправлено в очередь, но не будет ждать, пока микросервис 2 завершит обработку сообщения.

Интеграция обмена сообщениями действительно отличается от конечных точек веб-API RESTful или gRPC с точки зрения архитектуры. Микросервисы отделены друг от друга. Нет необходимости изменять и перекомпилировать код клиентского микросервиса, если его сообщение завтра нужно доставить большему количеству потребительских микросервисов, чем сегодня.

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

Однако в случае сбоя компонента служебной шины приложение перестанет работать. Служебная шина должна быть высокодоступной, чтобы не быть единой точкой отказа.

Потоковая интеграция

Когда интеграция потоковой передачи реализуется через брокера потоковой передачи (например, Kafka, Redis), она архитектурно похожа на интеграцию обмена сообщениями с точки зрения разделения микросервисов. Обратите внимание, что потоковую передачу можно выполнять без брокера потоковой передачи через инфраструктуру gRPC, но в этом случае службы будут тесно связаны.

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

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

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

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

Краткое содержание

Конечные точки веб-API RESTful и стили интеграции RPC хорошо подходят для синхронной связи между микрослужбами, когда клиентская микрослужба должна инициировать запрос и ждать ответа. Однако оба подхода приводят к тесной связи между микросервисами и вопросами управления версиями.

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

Спасибо за прочтение. Если вам понравилось то, что вы прочитали, ознакомьтесь с этой историей ниже: