Архитектура бэкенда
Идемпотентность и retry: тест с выбором ответа
Шесть вопросов поперёк всего юнита. Ни один не определение для заучивания — каждый это решение под нагрузкой, где неверный выбор это двойное списание, потерянное событие или самим себе устроенный outage.
Убедись, что связываешь все движущиеся части, к которым вели уроки: idempotency key, серверную машину состояний, retry с jitter, композицию outbox + inbox и гонки конкурентности, которые превращают аккуратный дизайн в дублированный side effect.
Мобильный клиент отправляет POST /charge, ответ теряется, и он делает retry. На retry он генерирует свежий UUID в заголовок Idempotency-Key. Каково последствие и почему?
Запрос приходит с Idempotency-Key K1. Сервер находит строку K1 со status=in_progress. Почему вернуть 409 сразу, а не блокироваться до завершения первого запроса?
Сервис возвращает 503 с Retry-After: 30 во время outage. По всему флоту какое поведение клиента оставляет восстанавливающийся сервис живым?
Команда должна публиковать событие 'order.created' в Kafka каждый раз, когда строка заказа коммитится в Postgres. Почему outbox-паттерн верен, а «записать Postgres, потом опубликовать Kafka» нет?
Два запроса с одним и тем же idempotency key приходят на сервер в пределах миллисекунды. Хендлер делает SELECT-потом-INSERT в таблицу idempotency_keys. Что произойдёт и какой фикс?
Платёжный API использует только Redis (async fsync, SETNX) как хранилище idempotency. Нода падает через миллисекунду после SETNX, теряя этот ключ. Какое production-чтение этого дизайна?
Юнит — это одна цепочка: клиент делает retry с одним ключом на операцию; сервер разрешает этот ключ в new / in-flight (409) / replay / mismatch (422) и атомарно сохраняет результат через ON CONFLICT; retry используют full jitter, уважают Retry-After и живут под общим retry budget; outbox + at-least-once relay + dedup в inbox превращают невозможную dual-write в effectively-once; а durable-хранилище должно пережить сбой, потому что потеря ключа — это и есть превращение аккуратного дизайна в двойное списание. Каждый production-сбой юнита — Stripe 2017, Knight Capital, AWS S3, GitHub 2018 — это at-least-once без идемпотентных консьюмеров или retry без jitter.