TGViewer
Павел Сорокин | Java Павел Сорокин | Java @s0r0kln · 9.16K subscribers
Post #212 4.99K
Почему нужно делать запросы идемпотентными, и как это реализовать

Когда проектируешь современное приложение — особенно если это распределенная система (микросервисы) — нужно быть предельно аккуратным.

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

Допустим, у нас банковская система. Сервис №1 (клиент) отправляет другому сервису №2 (сервер) запрос: "Зачислить 100 рублей на счёт Васи".

1. Сервер обработал, деньги зачислил (в БД байтики подвигал).
2. Но клиент не получил ответ (он долго шел или сеть оборвалась)
3. Клиент решает: «Ну ладно, отправляем еще раз».
4. И отправляет тот же самый запрос. Сервер получает его и... снова зачисляет 100 рублей.

Поздравляю. Мы только что подарили Васе 100 рублей.

Это реальность в распределённых системах. Это случается, если ты не реализуешь идемпотентность.

💡 Что вообще такое идемпотентность?

Если по-простому: это такое поведение, при котором многократный вызов одной и той же операции с одними и теми же параметрами даёт один и тот же результат.

— Умножение любого числа на 1 — идемпотентно (или прибавление 0).
— Повторные запросы GET/PUT/DELETE идемпотенты

А вот "прибавить к балансу 100 рублей" — не идемпотентно. Если сделать ее два раза — результат будет другим.

Обычно, POST-запросы — не идемпотентные.


💡 Как нам сделать так, чтобы повторный запрос не привёл к повторной операции?

1. Заводим idempotency key — уникальный идентификатор запроса. Передаем в заголовке X-Idempotency-Key
2. Каждый запрос, который может быть ретрайнут, должен иметь этот ключ.
3. Это может быть UUID, который генерится на клиенте или где-то на гейтвее.

Когда сервер получает запрос:

1. Он смотрит, не обрабатывал ли он уже запрос с таким ключом.
2. Если да — он возвращает результат той самой обработки, без повторения действий.
3. Если нет — выполняет операцию и сохраняет результат вместе с ключом.

💾 Где и как хранить обработанные ключи?

Есть несколько популярных вариантов:

— Redis — идеально для временного хранения. Можно задать TTL (время жизни ключа), чтобы не захламлять память. Быстро, просто. Есть риск потерять данные.

— PostgreSQL или другая SQL-БД — если нужна надёжность и долговечность. Но медленнее. Если у вас несколько тыс RPS, то спокойно подойдет.

— В самой бизнес-сущности — например, если обрабатываешь платёж, можно добавить поле "идемпотентный ключ", и искать по нему. Либо в этом случае ключом идемпотентности может выступать уже существующий идентификатор операции, а не какой-то искусственный ключ.

TTL — почти обязательно. Иначе за год таких ключей накопится миллиарды. Обычно TTL ставят от 1 часа до пары суток — зависит от критичности. Если нужны очень жесткие гарантии и запросы могут долететь через недели - можно хранить несколько лет или всегда.

⚠️ Какие есть нюансы?

— Запрос ещё в процессе — возвращаем статус типа "Processing", и говорим клиенту подождать (можно с Retry-After) + HTTP code 202

— Ошибка при выполнении: нужно различать ошибки:
 • Системная (например, упала БД) — можно ретраить.
 • Валидация или бизнес-ошибка — ретрай не поможет

Короче: на каждый запрос с ключом — должен быть один и только один побочный эффект.

Система без идемпотентности ненадежна и может приводить к неожиданным и нежелательным последствиям. Это, кстати, относится не только к входящим http запросам. Может быть такое, что при отправке в брокер сообщение задублировалось — на потребителе нужно проверять дубликаты (реализовать можно аналогично через заголовок и ключ)

👍 — знал
🔥 — не знал

#хардовая_польза
  • 🔥 90
  • 👍 46
  • ❤ 9
  • ✍ 2
More from @s0r0kln
  1. Oct 9, 2026Еще пару часов рабочей недели и можно выдохнуть, а пока, уже по традиции: кидай в комменты…
  2. Oct 8, 2026Мы уже разбирали паттерны микросервисов, это часть 2 Есть ещё 5 ребят, без которых распред…
  3. Sep 21, 2026Нужна ваша помощь 😐 В общем, я сейчас планирую 2 эфира сделать в сентябре - навалить поле…
  4. Sep 21, 2026Я очень много работаю с нейронками. Но есть вещи, которые я им не доверяю Код написать, ош…
  5. Sep 17, 2026Иллюзия понимания. Мне нередко в комментах на ютубе пишут что-то в духе "Паша, ну ты ваще…
  6. Sep 16, 2026Памятка по подготовке к собесу
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →