Вопрос с собеседования · System design

Как сделать обработку запросов надёжной при сбоях и повторах?

MiddleНадёжность и идемпотентность
Ещё спрашивают так:
  • Как обрабатывать сбои при вызове других сервисов?
  • Что делать с сообщением, которое постоянно падает при обработке?
Коротко

Сбои неизбежны, поэтому: таймауты на каждый вызов, повторы с отсрочкой и джиттером, идемпотентность операций, чтобы повтор был безопасен, circuit breaker против долгих отказов и DLQ для сообщений, которые не обрабатываются.

  • Повтор без идемпотентности = дубли платежей и заказов
  • Ключ идемпотентности хранится вместе с результатом операции
  • Ограничить повторы: число попыток, бюджет, один уровень цепочки

А ещё Outbox — чтобы изменение данных и событие не разошлись

Подробно

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

Повторы снимают кратковременные сбои: экспоненциальная отсрочка (100, 200, 400 мс…) и джиттер — случайная добавка, чтобы клиенты не повторяли синхронно. Повторять только временные ошибки (таймаут, 503) и ограничивать: 2–3 попытки, бюджет повторов.

Идемпотентность делает повтор безопасным: операция с тем же ключом выполняется один раз. Клиент передаёт Idempotency-Key, сервер сохраняет ключ и результат в одной транзакции с бизнес-изменением. Для сообщений из брокера (доставка «хотя бы один раз») — таблица обработанных id или естественно идемпотентные операции (UPSERT, «установить статус», а не «прибавить»).

Circuit breaker — если зависимость стабильно отказывает, перестать её вызывать на время (быстрый отказ или запасной ответ), потом пробовать осторожно. Защищает и себя, и упавший сервис.

Изоляция (bulkhead) — отдельные пулы для разных зависимостей, чтобы одна медленная не съела все потоки.

Очередь недоставленных (DLQ) — сообщение, которое падает после N попыток, перекладывается в отдельную очередь, чтобы не блокировать поток и не теряться; оттуда его разбирают и переигрывают.

Согласованность данных и событий — transactional outbox: событие пишется в ту же транзакцию, что и данные, а отправляется отдельным процессом.

Что хотят услышать

  • Таймауты, повторы с отсрочкой и джиттером, ограничение повторов.
  • Идемпотентность как условие безопасного повтора, ключ идемпотентности.
  • Circuit breaker и bulkhead.
  • DLQ для «ядовитых» сообщений, outbox — плюс.

Частые ошибки

  • Повторять неидемпотентные операции.
  • Бесконечно повторять «ядовитое» сообщение, блокируя очередь.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✗Повторять запрос сразу и без ограничений, пока не пройдёт
  • ✗Увеличить таймауты до минуты, чтобы запросы реже обрывались, и отключить повторы на клиенте
  • ✓Таймауты, повторы с отсрочкой и джиттером, идемпотентность, circuit breaker, DLQ
  • ✗Распределённая транзакция на каждый запрос

Что спросят дальше

  • Что такое circuit breaker?
  • Зачем jitter в backoff?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.

Разбор собеседования