Синхронная и асинхронная коммуникация в сервисах | Блог Кирилла Грищука

Введение
Эта тема все еще вызывает трудности, поэтому решил подготовить собственную статью с пояснениями.
Поговорим о двух парадигмах для связи асинхронная и синхронная.
Эта статья не ограничивается взаимодействием нескольких систем, а скорее про проблемы возникающие вокруг коммуникации, но на примере взаимодействия двух систем.
Практический пример
Обсудим в чем принципиальные отличия этих подходов.
Представим, что у вас есть вопрос и вам срочно нужно получить ответ на него от друга.
В синхронной модели вы позвоните ему, получите ответ, завершите звонок. Ответ получен сразу или не получен вовсе (например ваш друг не берет трубку).
В асинхронной модели вы можете написать сообщение другу и пока не получили ответ заниматься другими делами.
Подробно поговорим о характеристиках
Синхронный вызов
Плюсы:
- Ответ известен сразу
 - Самый простой и распространенный, большинство обработчиков и контроллеров работают так
 - Идеально для малых нагрузок
 - Консистентность возможна, но требуются механизмы для управления транзакциями, например 2PC. Разберем следующие случаи коммуникаций.
- Получатель смог все обработать, а отправитель упал - все плохо
- Появляются мертвые записи и объекты без привязки
 
 - Отправитель ждет ответа, а получатель упал - все хорошо - запрос отвалится по ожиданию обработки.
 - Полная консистеность возможна, возможно видеть самые последние изменения.
 
 - Получатель смог все обработать, а отправитель упал - все плохо
 
Минусы:
- Блокировка до ответа
- Ожидание ввода/вывода. Железо простаивает, в момент ожидания ответа, не обрабатывая другие вопросы, но применимо не ко всем языкам и технологиям, реализации могут парковать потоки или отдавать в пул.
 - Возможна утечка ресурсов при неправильно подобранных таймаутах и политиках повторных запросов, каскадный отказ системы по таймаутам.
 
 - Снижение отказоустойчивости
- Плохой паттерн для работы под нагрузкой, в прямых вызовах отсутствует журналирование, ведение лога сообщение и при критичных проблемах, восстановление потребует время + необработанные запросы будут потеряны
 - Например когда второй сервис отвечает долго и у нас таймаут и ретраи и мы еще больше грузим систему, возможен каскадный резонанс всей системы
 
 
Асинхронный
Плюсы:
- Высокая отказоустойчивость
- Отказ одного компонента ведет к наполнению очередей обработки, а не каскадному резонансу
 - Возможнотсть обработать запросы повторно при ошибках
 
 - Самый распространенный способ отмасштабировать систему и размазать нагрузку
- Шлем ивенты
 - Добавляем обработчики
 
 
Минусы:
- Результат недоступен сразу, а появлется с задержкой -> проблема актуальности данных
 - Реализуется сложнее, требуется промежуточное хранилище, еще одна система для хранения данных
 - Делает систему eventually consistent
- Состояние актуальное, но через какое-то время
 - Есть паттерны для цепочек транзакций между сервисами например SAGA, но от проблем отката никто не застрахован
 
 - Гарантии доставки ограничены
- Невозможно реализовать доставку ровно 1 раз
 - Все популярные системы дают гарантии at most 1, at least 1
 - Требуется паттерн (Transaction outbox) для гарантии записи
 - Сложность реализации идемпотентных операций
 
 
Дополнительные источники для изучения:
- https://serverlessland.com/event-driven-architecture/visuals/sync-vs-async
 - https://www.mendix.com/blog/asynchronous-vs-synchronous-programming/
 - https://bitbytesoft.com/synchronous-and-asynchronous-programming/
 - https://www.koyeb.com/blog/introduction-to-synchronous-and-asynchronous-processing
 - https://www.outsystems.com/blog/posts/asynchronous-vs-synchronous-programming/
 - https://www.youtube.com/watch?v=3D2kYmEa8rk
 - https://developers.redhat.com/articles/2021/09/21/distributed-transaction-patterns-microservices-compared
 - https://microservices.io/patterns/data/saga.html
 - https://www.baeldung.com/cs/saga-pattern-microservices
 - https://medium.com/design-microservices-architecture-with-patterns/saga-pattern-for-microservices-distributed-transactions-7e95d0613345
 - https://blog.avenuecode.com/saga-pattern-for-microservices-architecture
 
kirya522.tech — Блог Кирилла Грищука о разработке