Синхронные и асинхронные взаимодействия

Я помогаю Golang, Java и C# разработчикам находить работу и проходить собеседования: резюме и отклики, которые доходят до HR, спокойный собес и торг по офферу. Разбираю механику найма изнутри, я провёл более 100 собеседований. Без воды, только чек-листы и готовые фразы.

синхронные взаимодействияасинхронные взаимодействияброкер сообщений

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

🔄 Синхронные взаимодействия

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

📝 Пример

Рассмотрим бизнес-сценарий регистрации пользователя в системе, который разбивается на следующие шаги:

  1. Создать пользователя в БД
  2. Отправить сообщение по email с ссылкой активации

Представим два компонента системы: сервис пользователей (User) и сервис отправки email (Email). Тогда последовательность выглядит так:

  1. Пользователь отправляет HTTP-запрос "Создать пользователя" в User
  2. User сохраняет пользователя в БД и отправляет HTTP-запрос "Отправить email" в Email

⚠️ Проблемы синхронного взаимодействия

Компоненты, взаимодействующие синхронно, являются сильносвязаными. Доступность сценария равна произведению показателей всех компонентов, так как для успешного выполнения нужны все сервисы. Если User и Email имеют показатели доступности 99.8%, то финальный показатель - 99.6%. Чем больше сервисов в цепочке, тем меньше значение показателя.

В итоге пользователи не могут зарегистрироваться, если Email недоступен. Также сервис User ждет ответа Email синхронно, что может приводить к негативному пользовательскому опыту из-за ожидания выполнения запроса "Отправить email" в рамках сценария.

Для решения выше изложенных проблем можно использовать асинхронные взаимодействия.

🚀 Асинхронные взаимодействия

Асинхронное взаимодействие - это взаимодействие между компонентами системы, которое не подразумевает мгновенный ответ.

📨 Брокеры сообщений

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

🎯 Решение проблемы

Бизнес выпустил новые требования: регистрация пользователя должна работать при недоступности сервиса Email.

Целевую схему с использованием асинхронного взаимодействия можно описать так:

  1. Пользователь отправляет HTTP-запрос "Создать пользователя" в User
  2. User сохраняет пользователя в БД и отправляет событие "Пользователь создан" в брокер сообщений
  3. Email обрабатывает сообщение "Пользователь создан" и отправляет письмо пользователю.

✅ Преимущества асинхронного подхода

Брокер сообщений позволяет отвязать логику создания пользователя от взаимодействия с сервисом email.

Теперь показатель доступности бизнес-сценария регистрации равен произведению показателя User на показатель брокера. В упрощенных расчетах показатель доступности брокера часто принимают за единицу, так как без него распределенные бизнес-сценарии не выполняются. Поэтому можно допустить, что доступность бизнес-сценария теперь определяется доступностью User. Таким образом удалось отвязать логику сервиса User от Email и добиться создания пользователей даже при неработающем сервисе Email. Рано или поздно сервис email обработает события и отправит письма.

🔧 Дополнительные паттерны

Можно избежать связи с брокером, если использовать паттерн Transactional Outbox, так как он выносит обращение к брокеру из бизнес-сценария в фоновую задачу.

🎯 Вывод

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

Асинхронные взаимодействия используются в клиент-серверном взаимодействии для обмена сообщениями. Например, с использованием SignalR. В распределенных системах используются для обмена событиями о бизнес-действиях, как "Пользователь создан" в нашем сценарии, и отправки команд, которые не требуют ответа в другие сервисы. Например, можно было бы заменить событие "Пользователь создан" на команду "Отправить Email".

#техничка #backend

Читайте так же