Как принимать решение о синхронной или асинхронной интеграции
Что проверяют
Умеете ли вы выбирать способ интеграции по требованиям, а не по моде. Интервьюер хочет услышать про связанность, задержку, отказоустойчивость и согласованность данных. Следом почти всегда спрашивают, что будет, если сообщение потеряется или придёт дважды.
Как отвечать
Начните с вопроса: нужен ли вызывающей стороне результат прямо сейчас, чтобы продолжить работу. Если да, интеграция синхронная, если нет, асинхронная.
- синхронно (REST, gRPC): проверка остатка перед заказом, авторизация платежа, всё, от чего зависит ответ пользователю. В Spring это
RestClient,WebClientили Feign. Обязательны таймауты, повторы с задержкой и circuit breaker из Resilience4j. Минус: временная связанность, упал сосед, упали и вы, а задержки цепочки складываются; - асинхронно (Kafka, RabbitMQ): письма, начисление бонусов, синхронизация справочников. Сервисы развязаны по времени, брокер сглаживает пики. Цена: итоговая согласованность и более сложная отладка, нужна трассировка через заголовки сообщений;
- надёжность: брокер даёт at-least-once, значит потребитель идемпотентен. Чтобы запись в базу и отправка события не разъехались, используют transactional outbox;
- ошибки: в синхронной модели их сразу видит клиент, в асинхронной нужны ретраи, dead letter topic и мониторинг лага потребителей;
- гибрид: принять запрос синхронно, вернуть
202 Acceptedс идентификатором операции и доделать в фоне.
Хорошо подкрепить ответ примером из своего проекта: что выбрали и какие метрики смотрели (p99 задержки, лаг, доля ошибок).
Где спотыкаются
Путают асинхронную интеграцию с асинхронным кодом. CompletableFuture или @Async не делают интеграцию асинхронной: соседний сервис по-прежнему должен быть доступен в момент вызова.
Считают, что очередь сама решает надёжность. Без идемпотентности и outbox при первом же рестарте появятся дубли или потерянные события.
Строят синхронные цепочки из пяти сервисов без таймаутов. Один медленный участник исчерпывает пулы потоков у всех, кто стоит выше.