Anton Sidorov homepage

Bookmark this to keep an eye on my project updates!

Follow me on GitHub

Идемпотентность

Зачем

Обеспечить Fault Tolerance и реализовать паттерн Failure.

Проблема:

Решение:

  • Идемпотентным называют такой метод API, повторный вызов которого не меняет состояние ресурса\сущности. НО: результат идемпотентного вызова может меняться.
  • Использования уникального ключа идемпотентности для каждой транзакции

В ИС потребителе

  • ключ идемпотентности генерится
  • необходимо отделить создание idempotency_key от области передачи отправки, практика: Добавить шаг подтверждения перед шагом отправки
  • поле заголовка HTTP Idempotency-Key
  • Ключ идемпотентности обязательно создавать в формате GUID. Рекомендуется версия 4.

На сервере ИС источник

  • Необходимо проверять, что параметры входящего запроса совпадают с параметрами существующего запроса с таким же ключом идемпотентности.
    • Варианты ответов (применение от необходимости обработки на клиенте)
    • Чтобы детерминировано определить ключ идемпотентности как для изначального сообщения, так и для повторно обработанного, можно использовать хеш его содержимого или хеш уникальных для сообщения полей.
    • уникальность ключа должна проверяться не глобально, а только применительно к конкретному пользователю и конкретной операции
  • необходимо хранить ключ идемпотентности
    • инсертится в базу в поле, на котором есть ограничение базы данных по уникальности. Если это ограничение не дало сделать инсерт, то отдавать ошибку (HTTP status 409).
    • или NOSQL (Redis)
  • необходимо определить время жизни (TTL) ключа идемпотентности исходя из бизнес логики бизнес операции
  • если ключ найден сервер\прокси\middleware может отдать предыдущий ответ (response, header) из кэша с учетом TTL, без выполнения запроса
  • Когда приходит дублирующий запрос, в то время как исходный все еще обрабатывается (параллельные запросы). Ответы на идемпотентные операции различаются в зависимости от состояния исходного запроса:
    • Завершено успешно – исходный код состояния и текст ответа извлекаются из кэша, например Momento, и возвращаются вызывающему абоненту.
    • Завершено с ошибкой — повторная попытка операции, как если бы она была исходной.
    • Выполняется — возвратить успешное выполнение и не выполнять никаких операций.

REST HTTP методы

  • идептоментны всегда: GET, PUT, DELETE
  • необходимо реализовать идептоментность
    • POST - клиент должен контролировать повторные запросы, если не получил ответа
    • PATCH - если клиент не получил ответа на запрос, просто направляет повторно
  • Прокси-серверы могут не повторять POST и PATCH запросы при ошибках, тогда как GET и PUT могут повторить.

Message Bus

  • Чтобы гарантировать идемпотентность MQ, необходимо гарантировать, что потребители не будут повторно использовать одно и то же сообщение.

Синхронизировать знание о списке ресурсов на клиенте и сервере через версионирование этого списка

При создании заказа приложение передает в отдельном поле или заголовке If-Match версию, о которой он знает.

  • Сервер атомарно с изменением увеличивает версию при любых изменениях заказов (создание, отмена, редактирование).
  • То есть приложение в запросе к серверу говорит ему, какое состояние заказов оно знает. И если это состояние заказов (версия) расходится с тем, что хранится на сервере, то сервер отдает ошибку «заказы были изменены параллельно, перезагрузите информацию о заказах».

Технологии