johnymkp
@johnymkp

Как работает синхронный вызов в микросервисах?

Читаю книгу Сэма Ньюмена "Создание микросервисов", там есть такая фраза:

> With a synchronous blocking call, a microservice sends a call of some kind to a
downstream process (likely another microservice) and blocks until the call has com‐
pleted, and potentially until a response has been received.

В русском переводе:

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

Я хочу уточнить - блокируется микросервис (мс) вообще целиком или все-таки только поток, из которого сделан вызов?

Я себе представляю работу так: пусть у нас 2 мс, А и В, сделаны на Spring Web или любом другом веб-фреймворке. Каждого мс по одному экземпляру.
* Пользователь что-то щелкает.
* запрос уходит в А.
* в А создается новый поток (или берется из пула - не важно) для обслуживания пришедшего запроса.
* А вызывает В и ждет от него ответа.
* при этом блокируется не весь А, а только поток, который обслуживает запрос.

Стало быть, если другой пользователь тоже что-то щелкнет, то его запрос тоже будет обслуживаться отдельным потоком, и поэтому сам мс А не блокируется, продолжает нормально работать. Так почему тогда в книге написано, что блокируется микросервис?
  • Вопрос задан
  • 66 просмотров
Решения вопроса 2
vabka
@vabka
Токсичный шарпист
Я хочу уточнить - блокируется микросервис (мс) вообще целиком или все-таки только поток, из которого сделан вызов?

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

Я себе представляю работу так: пусть у нас 2 мс, А и В, сделаны на Spring Web или любом другом веб-фреймворке. Каждого мс по одному экземпляру.
* Пользователь что-то щелкает.
* запрос уходит в А.
* в А создается новый поток (или берется из пула - не важно) для обслуживания пришедшего запроса.
* А вызывает В и ждет от него ответа.
* при этом блокируется не весь А, а только поток, который обслуживает запрос.

Условно так, но на практике даже поток не будет блокироваться - только обработка запроса от пользователя (пользователь не получит ответ, пока B не вернёт ответ)

Стало быть, если другой пользователь тоже что-то щелкнет, то его запрос тоже будет обслуживаться отдельным потоком, и поэтому сам мс А не блокируется, продолжает нормально работать. Так почему тогда в книге написано, что блокируется микросервис?

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

Речь идет о блокировании микросервиса с "логической" точки зрения. В книге фраза из вопроса, как оказалось, находится в контексте модели взаимодействия "запрос-ответ". Эта модель подразумевает, что когда сервис А делает запрос к сервису В, то А требуется ответ, чтобы продолжить выполнять бизнес-задачу.

Например, бизнес-задача выглядит так: "Зарезервировать нужный товар на складе, и только потом принять оплату". Тогда сервис А отправляет сервису В запрос "зарезервируй такой-то товар на складе" и пока не получит ответ "товар зарезервирован" - не сможет принять оплату. Т.е. здесь запрос на резервирование вызывает "логическую" блокировку сервиса, которая с "технической" блокировкой связана очень косвенно.

Технически этот бизнес-сценарий можно выполнить двумя способами - блокирующим и неблокирующим:
  • Блокирующий подразумевает, что поток сервиса А отправляет запрос к В и ЖДЕТ ответа, т.е. не идет дальше, пока ответ не получен. При этом сервис А в целом продолжает работу - он сам может принимать новые запросы, потому что они обрабатываются разными потоками. Здесь важно отметить, что в зависимости от технической реализации, вовсе не обязательно, что поток блокируется после отправки запроса и до получения ответа. Асинхронная отправка может работать так, что отправляет запрос один поток, а ответ обрабатывает другой. Поэтому блокирующий подход не обязательно означает, что в случае долгих ответов пул потоков исчерпается и все встанет. Но тем не менее, если в технические подробности не углублятся, со стороны все выглядит так, будто поток заблокирован. Поэтому этот способ и называется блокирующим.
  • Неблокирующий подразумевает, что поток сервиса А отправляет запрос к В и НЕ ЖДЕТ ответа. Обработка ответа реализуется другим способом (но это уже другая история, к вопросу не относящаяся). Т.е. здесь концептуально другая схема работы - поток, делающий запрос, никак не занимается обработкой ответа, а значит ему нет нужды ждать ответ. Поэтому этот способ называется неблокирующим.


Возможно, получилось с привкусом канцелярщины, но постарался описать так, как понятно самому.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
AshBlade
@AshBlade
Просто хочу быть счастливым
блокируется микросервис (мс) вообще целиком или все-таки только поток, из которого сделан вызов?

Блокируется поток (т.к. коммуникация идет с гранулярностью в 1 поток).

Блокирующий вызов означает, что вызывающая сторона ОЖИДАЕТ ответа.
Это сравнивается с НЕБЛОКИРУЮЩИМИ запросами, например, запись в очередь.

Примеры блокирующих:
- HTTP
- gRPC
- отправляешь сообщение в одну очереди и начинаешь читать ответ из другой (это тоже блокирующий)

Примеры НЕблокирующих:
- Kafka, Rabbit
- Outbox (паттерн)

Так почему тогда в книге написано, что блокируется микросервис?

Значит, неправильно описал, не те слова подобрал
Ответ написан
sergey-gornostaev
@sergey-gornostaev
Седой и строгий
Блокируется поток, но радоваться этому не стоит. Если потоки берутся из пула, то пул ведь не резиновый. Пользователь может что-то щёлкнуть много раз или пользователей может быть много, потоки в пуле кончатся и весь сервис зависнет. Если потоки создаются на каждый запрос - ещё хуже, большое количество запросов просто сожрёт все доступные сервису ресурсы и он грохнется или поставит колом не один сервис, а все выполняющиеся на этом сервере.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы