Взаимодействие в архитектуре микросервисов
Микросервисная архитектура позволяет разделять сервис на отдельные функции, независимо масштабировать отдельные части, обеспечивать повышенную устойчивость к сбоям, использовать разные технологии под разные задачи и не только. Но переход от монолитной архитектуры к микросервисной — сложный процесс, самым трудным этапом которого является изменение механизма взаимодействия внутренних компонентов.
Разбираемся, в чем трудности перехода и как устроено взаимодействие в архитектуре микросервисов.
Монолит vs микросервис
Микросервисная архитектура появилась в тот момент, когда работать «монолитами» стало сложно и неудобно. С новым принципом построения приложений, микросервисы получили и совершенно другой принцип взаимодействия компонентов — в монолитной архитектуре применяют внутрипроцессные взаимодействия, а в микросервисной взаимодействие модулей происходит через сеть по протоколонезависимой технологии.
Сравнение монолитной и микросервисной архитектур. Источник
Кроме того, в монолитах компоненты обращаются друг к другу на уровне кода или функции и выполняются в рамках одного процесса. Прямое изменение внутрипроцессных вызовов в вызовы удаленных процедур к сервисам не позволит получить взаимодействие, которое подойдет распределенным средам.
Как решать ситуацию
Унифицированного решения, позволяющего обеспечить правильное взаимодействие при переходе на микросервисы нет — для каждой ситуации нужно свое.
Одно из подобных — изоляция бизнес-значимых микросервисов. При реализации такого решения внутренние микросервисы будут взаимодействовать асинхронно и менее детально. При этом вызовы будут группироваться, данные из нескольких служб агрегироваться и только после отправляться клиенту.
Второй вариант — создание архитектуры, при которой отдельные микросервисы будут частично зависимы, но максимально согласованы. При этом следует учесть, что каждый микросервис должен иметь свои данные и логику.
Типы связи
Взаимодействие клиента и сервиса может быть реализовано с помощью разных типов связей. Их можно разделить на две группы.
Первая группа
Устанавливает тип протокола — асинхронный или синхронный.
Асинхронный протокол. Код клиента или отправители сообщения не ждут ответ — сообщения отправляются аналогично передаче в очередь любого брокера. Такой тип применяет протокол AMQP.
Синхронный протокол. При отправке запроса клиент ожидает ответ от службы — задачи выполняются только после того, как сервер пришлет ответ. Пример такого протокола — HTTP.
Вторая группа
Устанавливает, сколько получателей у запроса.
Один получатель. Каждый запрос обрабатывает конкретный получатель или сервис.
Несколько получателей. Для каждого запроса количество получателей отличается. Взаимодействие выстраивается с использованием асинхронных протоколов.
В микросервисных приложениях часто используют связку двух стилей. Например, для взаимодействия с одним получателем — синхронный протокол, а для асинхронного — протоколы сообщений.
Но при создании микросервисов больше́е значение имеет не тип связи, а возможность асинхронной интеграции микросервисов без снижения их независимости.
Асинхронная интеграция как способ обеспечения автономности микросервисов
При создании приложений с микросервисной архитектурой важно правильно реализовать способ интеграции — в идеале, чтобы внутренние микросервисы взаимодействовали между собой минимально, а взаимодействие было асинхронным.
Следует понимать, что использование синхронного взаимодействие между несколькими микросервисами не лучший вариант — каждый микросервис должен быть автономным и доступным клиенту, даже если другие сервисы отключены или недоступны. Если это не реализовать, архитектура будет неустойчива к сбоям — при недоступности одного сервиса будет недоступно все приложение.
Кроме того, наличие зависимостей HTTP между микросервисами влияет не только на их автономность, но и на быстродействие — чем меньше синхронных зависимостей, тем выше скорость отклика в клиентском приложении.
Паттерны взаимодействия между микросервисами. Источник
Преимущество асинхронного типа связи в том, что запрос клиента обрабатывается сразу, в то время, как при синхронной модели вся обработка выполняется одновременно. Поэтому синхронный способ взаимодействия лучше не использовать в рамках исходной операции «запрос-ответ».
Асинхронный тип связи можно использовать, даже если исходному микросервису нужны данные из другого микросервиса. В такой ситуации отказаться от синхронных запросов можно, делая реплики данных в базу данных — это допустимо.
Исходя из этого, главное что нужно понимать — не используйте синхронные зависимости между микросервисами.
Стили взаимодействия
В приложениях на базе микросервисов можно использовать разные стили внутреннего взаимодействия модулей. Например:
если взаимодействие выполняется за пределами узла Docker или кластера микросервиса, то лучше подойдет механизм синхронных запросов и ответов;
если взаимодействие выполняется в пределах узла Docker или кластера, подойдет комбинированный формат взаимодействия или асинхронное взаимодействие на базе сообщений (например, AMQP).
Кроме того, можно использовать и нестандартный комбинированный метод, но такой вариант подойдет только для внутреннего взаимодействия на узле или кластере — сервисы с таким форматом лучше не публиковать.
Операция «запрос-ответ» с использованием HTTP и REST
При использовании взаимодействия типа «запрос-ответ», клиентский запрос поступает к службе, которая обрабатывает его и возвращает ответ. Такой тип взаимодействия — лучший вариант для запроса данных от клиентских приложений, поэтому он чаще применяется в архитектуре микросервисов.
Пример использования взаимодействия типа «запрос-ответ». Источник
Один из распространенных стилей архитектуры при подобном типе взаимодействия — REST. Подход основан на HTTP-протоколе и позволяет работать с HTTP-командами. Кроме того, сервисы REST подходят для разработки сервисов веб-API ASP.NET Core.
Push-уведомления и связь по протоколу HTTP
Еще один метод — асинхронное взаимодействие в формате «один ко многим» в режиме реального времени с платформами высшего уровня.
При таком варианте взаимодействия серверный код способен автономно отправлять доступные данные клиентам, а не дожидаться, пока он их запросит.
Пример асинхронного взаимодействия в формате «один ко многим». Источник
Один из популярный инструментов для выстраивания подобного взаимодействия для быстрой передачи данных с сервера клиентам — SignalR. При этом обработку выполняет протокол WebSockets с множеством подключенных WebSockets на стороне клиентов (один клиент — один WebSockets). Например, такой метод применяют в спортивных приложениях, когда нужно всем пользователям передать данные об изменении счета в матче.
Для тех, кто хочет узнать больше о паттернах интеграции микросервисов и их назначении
14 июля в 19:00 Слёрм проведёт открытый вебинар «Обзор паттернов интеграции микросервисов».
Спикер Петр Щербаков, Enterprise Architect, расскажет о 10 основных паттернах интеграции между приложениями или микросервисами и том, как они могут решить проблему интеграции между вашими системами.
Узнать больше и записаться