Как модифицировать архитектуру микросервиса, чтобы обеспечить надежность обработки заказов при падении аналитического сервиса
Что проверяют
Умеете ли вы вывести второстепенный сервис из критического пути. Интервьюер ждёт, что вы сначала спросите, зачем заказу аналитика вообще, а потом предложите асинхронную схему. Следом обычно спрашивают, как не потерять события и не посчитать их дважды.
Как отвечать
Главная мысль: оформление заказа не должно ждать аналитику. Если сейчас заказ синхронно дёргает аналитический сервис по HTTP или gRPC, падение аналитики роняет продажи.
- асинхронность через брокер: сервис заказов публикует событие
OrderCreatedв Kafka, аналитика читает его в своём темпе. Упала на час, после подъёма дочитает с сохранённого оффсета. Только retention топика должен быть заметно больше самого долгого простоя; - transactional outbox: заказ и событие пишутся в одной транзакции базы, событие в таблицу
outbox. Отдельный процесс (горутина-релей или Debezium) переносит события в Kafka. Так не бывает ситуации «заказ сохранён, событие потеряно»; - идемпотентный потребитель: доставка at-least-once, поэтому аналитика дедуплицирует по
event_id; - если синхронный вызов неизбежен: жёсткий таймаут через
context.WithTimeout, circuit breaker (например,sony/gobreaker), который после серии ошибок перестаёт звать сервис и сразу уводит в запасной путь, и ограниченные ретраи с экспоненциальной задержкой и джиттером; - наблюдаемость: алерт на consumer lag аналитики и на рост таблицы outbox, иначе о проблеме узнают по пустым отчётам.
Хорошо закончить разделением: заказ это критичные данные с гарантиями, аналитика допускает задержку в минуты, и архитектура отражает эту разницу.
Где спотыкаются
Отправляют событие через go sendAnalytics(order) и считают вопрос решённым. При рестарте сервиса горутина умирает вместе с событием, а ошибку никто не увидит.
Пишут в базу, а потом отдельно в Kafka без outbox. Между двумя действиями процесс может упасть, и данные разъедутся.
Добавляют ретраи без брейкера и лимитов. Когда аналитика и так лежит, волна повторов от всех экземпляров мешает ей подняться.