Sync vs Async
При проектировании микросервисной архитектуры нередко возникает вопрос, какой именно способ связи между микросервисами лучше использовать. Конечно, всегда можно отдать предпочтение RESTful API, что и делают в большинстве случаев. Но на практике такой подход эффективен не всегда, ведь в отдельных ситуациях возможно долгое ожидание со стороны клиента и потеря информации при сбоях. Однако существует и другой вариант взаимодействия между микросервисами: очереди сообщений.
Message Queue представляет собой форму асинхронной коммуникации между сервисами. Именно асинхронной. Чтобы понять разницу между асинхронным и синхронным взаимодействием, давайте приведем простой и немного искусственный пример.
Представьте, что вы работаете над сайтом книжного магазина, причем у вас есть сервис, к которому пользователь систематически обращается, к примеру, в целях отправки отзыва на прочитанную книгу. Когда он нажимает кнопку «Отправить» происходит вызов некоторого API, который, кстати, может обращаться и к другим API.
В случае синхронного взаимодействия все запросы в данной цепочке вызовов будут выполняться в строгой последовательности друг за другом, причем при выполнении последнего запроса ответы так же последовательно будут передаваться обратно. По итогу пользователь станет несколько секунд ожидать сообщения о публикации отзыва, хотя он, разумеется, был бы рад увидеть сообщение сразу же после нажатия кнопки (и правда, его ведь не интересуют особенности вашей серверной обработки). Естественно, время ожидания станет во многом определяться мощностью оборудования, однако при пиковых нагрузках это замедление может превратиться в серьезную проблему.
Но выше описан не единственный недостаток синхронного взаимодействия, так как существует и другой минус: обработка сбоев. Когда на одном из шагов возникает исключение, это исключение каскадно возвращается назад, а пользователь получает уведомление об ошибке и неприятную просьбу отправить рецензию повторно. Такое сообщение, да еще и после долгого ожидания, вряд ли кого обрадует.
То есть синхронное взаимодействие на основе REST API можно представить следующей схемой:
Но эту схему мы можем изменить, если добавим асинхронные вызовы. Нам просто достаточно вызвать первый REST API в асинхронном режиме, параллельно с этим вернув пользователю сообщение, что его отзыв принят и будет размещен, допустим, в течение ближайших суток. Таким образом веб-сайт блокироваться не будет, а вызовы всех дальнейших API станут происходить вне зависимости от пользователя.
Но и у вышеописанной схемы будет недостаток, причем довольно серьезный: а что если произойдет сбой в одном из API? В таком случае информация, которая была введена пользователем, вообще может оказаться потерянной. Причем если в первом примере наличие ошибки привело бы просто к повторной отправке отзыва, то во втором случае форму отзыва пришлось бы заполнять заново, а это уже совсем никуда не годится.
REST API: возможный вариант асинхронного взаимодействия:
Как устранить недостатки обеих схем? Как раз для этого и нужны очереди сообщений (Message Queues). Но о них мы поговорим в следующий раз, следите за обновлениями блога!
По материалам https://mcs.mail.ru/blog/.