awesome-everything EN
↑ Обратно к восхождению

Архитектура бэкенда

Зачем идемпотентность: безопасные retry

Суть Сеть может проглотить ответ сервера. Без idempotency key клиент не может безопасно повторить запрос — каждый дублирующий POST рискует выполнить side effect дважды.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 10 min

Бея нажимает “Оплатить” на странице оформления заказа. Wifi пропадает до того, как ответ долетает. Она нажимает снова. У сервера нет способа отличить второй клик от первого — он списывает дважды.

Проблема сетевых гарантий

Интернет гарантирует at-least-once доставку, если клиент повторяет запросы до получения ответа, и at-most-once, если никогда не повторяет. Ни то ни другое само по себе не работает:

  • At-most-once — платёж, который не прошёл, потому что клиент сдался.
  • At-least-once без дедупликации — двойное списание.

Закрыть этот разрыв — задача приложения. Инструмент — идемпотентность.

Что такое idempotency key

Idempotency key — это непрозрачная клиентская строка, обычно UUID v4 (36 символов), передаваемая в HTTP-заголовке Idempotency-Key. Клиент выбирает один ключ на логическую операцию, а не на запрос. Каждый retry той же операции использует тот же самый ключ.

Сервер использует ключ как основной токен для ответа на вопрос: “я уже это обрабатывал?” Если да — возвращает исходный ответ без повторного запуска бизнес-логики. Если нет — обрабатывает и сохраняет результат.

СценарийБез ключаС ключом
Ответ доставлен1 списание1 списание
Ответ потерян, клиент ретраит 1 раз2 списания1 списание (replay)
Ответ потерян, клиент ретраит 3 раза4 списания1 списание (replay)
Ключ истёк до retryN/AОбрабатывается как новый — риск дубликата

Метафора: конверт и журнал

Представь, что отправляешь деньги через курьера. Помечаешь конверт “Заказ #A7-payment” и говоришь: “Если этот конверт уже доставили — не доставляй снова”. На каждом retry пишешь тот же номер заказа на новом конверте. Получатель проверяет журнал (idempotency cache) и либо доставляет конверт, либо говорит “уже сделано — вот квитанция”.

Журнал помнит. Без него каждый конверт выглядит новым.

HTTP-конвенция

Stripe популяризировал заголовок Idempotency-Key в 2014 году. Square, PayPal, Adyen и IETF-черновик draft-ietf-httpapi-idempotency-key-header следуют той же форме. RFC 9110 §9.2.2 перечисляет идемпотентные по спецификации HTTP-методы (GET, HEAD, PUT, DELETE, OPTIONS) — POST в этом списке нет, именно поэтому заголовок и существует.

Викторина

Какую проблему решает idempotency key?

Викторина

Ненадёжная сеть потеряла ответ на POST /charge. Что безопаснее всего сделать клиенту?

Расставь шаги по порядку

Поставь шаги безопасного retry в правильном порядке:

  1. 1 Клиент генерирует уникальный Idempotency-Key (UUID v4) для операции
  2. 2 Клиент отправляет POST с заголовком Idempotency-Key
  3. 3 Сеть или сервер падает до того, как клиент получает ответ
  4. 4 Клиент повторяет тот же POST с ТЕМ ЖЕ Idempotency-Key
  5. 5 Сервер узнаёт ключ и проигрывает кешированный ответ или завершает исходную работу
  6. 6 Клиент получает одно подтверждение и прекращает retry
Закончи аналогию

Заполни пропуск: idempotency key — это как метка на конверте с номером заказа, чтобы получатель проверил _______ перед повторной доставкой.

Вспомните перед уходом
  1. 01
    В чём разница between at-least-once и at-most-once доставкой, и почему ни то ни другое в одиночку не работает для платёжного API?
  2. 02
    Почему правило — один ключ на логическую операцию, а не один ключ на HTTP-запрос?
  3. 03
    Какие HTTP-методы идемпотентны по определению RFC 9110, и почему POST нуждается в заголовке?
Итог

Интернет не может доставить запрос ровно один раз — только at-most-once (без retry) или at-least-once (retry до подтверждения). Платёжному API нужно exactly-once поведение, для которого обе стороны должны cooperate: клиент ретраит с тем же заголовком Idempotency-Key, сервер дедуплицирует по этому ключу как по основному lookup-токену. Stripe популяризировал заголовок Idempotency-Key в 2014 году; IETF-черновик draft-ietf-httpapi-idempotency-key-header формализует его. Следующий урок разбирает серверный state machine, который делает это работающим.

Связанные уроки
встречается в179
Продолжить восхождение ↑Серверный state machine: четыре состояния idempotency key
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.