Как сделать обработку запросов надёжной при сбоях и повторах?
- Как обрабатывать сбои при вызове других сервисов?
- Что делать с сообщением, которое постоянно падает при обработке?
Сбои неизбежны, поэтому: таймауты на каждый вызов, повторы с отсрочкой и джиттером, идемпотентность операций, чтобы повтор был безопасен, 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?
Разбор темы
- Надёжность и идемпотентность
Управляемая деградация вместо каскада, таймауты и бюджет времени запроса, безопасные ретраи и их мультипликация, идемпотентность как фундамент, предохранитель, отсеки и сброс нагрузки, transactional outbox вместо 2PC.
Связанные вопросы
- Как правильно настраивать таймауты и повторы запросов? Middle
- В каких состояниях бывает circuit breaker и как он между ними переходит? Middle
- Что означает идемпотентность операции? Junior
- Клиент отправил POST для создания заказа, не дождался ответа из-за таймаута и повторил запрос. Как правильно не допустить второго заказа? Middle
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.