Микросервисный асинхронный отклик - PullRequest
3 голосов
/ 09 октября 2019

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

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

  1. пользователь отправляет http-запросна microservice1 (который является услугой, ориентированной на пользователя)

  2. microservice1 отправьте его на rabbitmq, потому что ему нужен какой-то сервис от microservice2

  3. microservice2, получит процесс запросаи отправьте ответ rabbitmq

  4. microservice1 получите ответ от rabbitmq

СЕЙЧАС, как этот ответ отправляется в браузер? Микросервис1 ждет, пока не получит ответ от rabbitmq? Если да, то как он стал асинхронным ??

Ответы [ 4 ]

1 голос
/ 09 октября 2019

Хороший вопрос. Чтобы ответить, вы должны представить, что сервер работает по одному потоку за раз. Создание запроса к микросервису через RestTemplate является блокирующим запросом. Пользователь нажимает кнопку на веб-странице, которая запускает ваш метод весенней загрузки в microservice1. В этом методе вы отправляете запрос microservice2, а microservice1 блокирует ожидание ответа.

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

RabbitMQ позволяет microservice1 ставить сообщение в очередь на microservice2, а затем освобождать поток. Ваше сообщение о получении будет инициировано системой (spring-boot / RabbitMQ), когда microservice2 обработает сообщение и предоставит ответ. Этот поток в пуле потоков может использоваться для обработки запросов других пользователей. Когда приходит ответ RabbitMQ, пул потоков использует неиспользуемый поток для обработки оставшейся части запроса.

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

0 голосов
/ 12 октября 2019

Я бы еще раз взглянул на вашу архитектуру. В целом, с микросервисами - особенно с обращенными к пользователю, которые должны быть по существу синхронными, это - анти-паттерн, когда ServiceA приходится звонить на ServiceB (что, в свою очередь, может вызывать ServiceC и т. Д. ...) чтобы вернуть ответ. Это условие указывает, что эти сервисы тесно связаны, что делает их хрупкими. Например: если ServiceB выходит из строя или перегружен в вашем примере, ServiceA также отключается из-за собственной ошибки. Поэтому, вероятно, должно произойти одно или несколько из следующих действий:

  • Развернуть связанные службы за фасадом, охватывающим весь домен, - разрешить клиенту синхронно взаимодействовать с фасадом и разрешить фасаду взаимодействовать с несколькими пользователями. сервисы за кулисами.
  • Используйте MQTT или AMQP для публикации данных по мере их добавления / изменения в ServiceB и имейте подписку ServiceA, чтобы получить то, что нужно, чтобы она могла выполнить запрос пользователя без явноговызов другой службы
  • Рассмотрите возможность объединения ServiceA и ServiceB в одну службу, которая может обрабатывать запросы без необходимости выполнения внешних вызовов

Вы также можете отправить HTTP-запрос изклиенту службы, установите для состояния приложения значение waiting или аналогичное и попросите приложение-потребитель подписаться на интеграционное сообщение eventSuccess или eventFail с шины. Суть этой идеи заключается в том, что вы позволяете сервисам с последовательным подключением (которые, опять же, мне не нравятся) по очереди, и какой бы сервис «не заканчивал» работу, публикует событие интеграции, чтобы каждый, кто слушает, знал. Вы даже можете сделать что-то вроде передачи URI webhook с первоначальным запросом, чтобы службы вызывали приложение сразу после завершения (или использовали SignalR, или gRPC, или ...)

Способ, которым мы используем RabbitMQ, заключается в интеграциисервисы в режиме реального времени, так что каждый сервис всегда имеет информацию, необходимую для быстрого реагирования. Чтобы использовать ваш пример, в нашем мире ServiceB публикует события при изменении данных. ServiceA заботится только о небольшом подмножестве этих событий и подписывается на небольшое подмножество этих событий (и, как правило, только на одно или два поля данных события), но в течение нескольких секунд (обычно меньше) знает, когда B изменилось, и у него есть всеинформация, необходимая для ответа на запросы. Каждый сервис буквально не знает, какие существуют другие сервисы, он просто знает, какие события, о которых он заботится (и которые соответствуют договору), происходят время от времени, и ему необходимо обращать на них внимание.

0 голосов
/ 09 октября 2019

Хороший вопрос, давайте обсудим один за другим

Синхронное поведение:

  • Клиент отправляет HTTP или любой запрос и ожидает ответа HTTP.

Асинхронное поведение:

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

Теперь мы можем говорить о блокировке по сравнению с неблокирующим вызовом

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

Теперь перейдем к вашему вопросу

Использование rabbitmq улучшает производительность микросервисов из-за асинхронного характера rabbitmq.

Нет , производительность зависит от вашего попадания TPS, и rabbitmq не собирается улучшатьсяпроизводительность.

Обмен сообщениями дает вам два типа обмена сообщениями

  • Синхронный обмен сообщениями
  • Асинхронный обмен сообщениями

Используя обмен сообщениями, вы получитеслабая связь и отказоустойчивость.

  • Если вашему приложению нужна блокировка вызова, как ResponТребуется, иначе нельзя двигаться, используйте Rest
  • Если вы можете работать без получения ответа, идите вперед с неблокирующими
  • Если вы хотите создать свое приложение, свободная пара отправляется с сообщениями.

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

Вы можете комбинировать свое приложение с отдыхом и обменом сообщениями и неблокировать с обменом сообщениями.

В вашем сценарии микросервис 1 может быть блокировать вызовы rest, вызывать другие API, используя шаблон rest или веб-клиент и / или очередь сообщений, и после получения ответа вернет вызов rest json вашему веб-приложению.

0 голосов
/ 09 октября 2019

Вы также можете использовать Event Sourcing и CQRS и сделать весь поток асинхронным. В этом сценарии microservice1 создает событие, представляющее запрос пользователя, а затем немедленно возвращает запрошенный созданный ответ пользователю. Затем вы можете уведомить пользователя позже, когда запрос будет завершен.

Я рекомендую книгу Проектирование управляемых событиями систем , написанную Беном Стопфордом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...