В КУРСЕ?

Разбираемся в теме

Запрос завершился тайм-аутом: почему повтор может создать второй заказ?

Клиент отправил запрос на создание заказа и не дождался ответа. Возникает соблазн немедленно отправить тот же запрос ещё раз. Но тайм-аут сообщает о проблеме ожидания, а не обязательно об отсутствии результата на сервере. Надёжная схема должна учитывать ситуацию, когда заказ уже создан, а ответ потерялся по дороге.

Разделите доставку запроса и бизнес-результат

Один и тот же внешний сбой может возникнуть до получения запроса сервером, во время обработки или после её завершения. С точки зрения клиента эти случаи иногда выглядят одинаково. Поэтому предположение ничего не произошло может оказаться неверным. Представим учебную операцию с обозначением A17. Сервер создал заказ, но соединение оборвалось до ответа. Повтор без распознавания операции может создать новый заказ. Если действие меняет данные, полезно сначала выяснить, как система определяет его идентичность и где можно узнать уже достигнутое состояние.

Идемпотентность относится к эффекту операции

Идемпотентное поведение означает, что повтор одной логической операции не создаёт дополнительного нежелательного эффекта по сравнению с её однократным выполнением. Для создания сущностей часто используют согласованный идентификатор операции или ключ идемпотентности. Такой ключ сохраняют для повторов именно того же намерения. Новая независимая покупка должна отличаться от повторной доставки старой. Серверу необходимо согласованно хранить связь ключа с состоянием и результатом. Простая проверка существования записи отдельно от её создания может оказаться недостаточной при двух одновременных запросах.

Повторяйте только подходящие сбои

Паттерн Retry помогает справляться с временными нарушениями связи или кратковременной недоступностью. Политика повторов задаёт ограничение числа попыток, задержки и условие прекращения. Увеличение паузы и случайный разброс времени могут уменьшить одновременный наплыв повторных запросов. Но неправильные входные данные не станут корректными от многократной отправки. Ошибку доступа тоже нельзя считать обычным поводом бесконечно повторять вызов. Нужно различать причины и соблюдать контракт сервиса. Если разные уровни приложения независимо повторяют один запрос, число попыток может неожиданно умножиться.

Сделайте состояние доступным для проверки

Для длительной обработки полезна отдельная сущность операции со статусом: принято, выполняется, завершено или отклонено. Клиент может обращаться за её состоянием, а не каждый раз запускать работу заново. Набор статусов и переходы между ними нужно определить заранее. Успешное принятие запроса не равно завершению бизнес-действия. Также важно договориться, сколько хранится ключ и как система отвечает на тот же ключ с другим содержимым. Идемпотентность не появляется от одного заголовка запроса: её обеспечивает согласованное поведение клиента, сервера и хранилища.

Попробуйте на практике

Проследите на бумаге обработку одного заказа с ключом A17 при потере ответа и повторной доставке.

  1. Нарисуйте три области: клиент, сервер и хранилище состояния. Запишите исходный запрос на создание одного заказа.
  2. Отметьте, что сервер завершил создание и сохранил результат для A17, но клиент не получил ответ.
  3. Проведите повтор с тем же ключом и тем же содержимым. Укажите, какой сохранённый результат должен быть использован.
  4. Добавьте второй сценарий: одновременно пришли две копии A17. Найдите место, где потребуется защита от параллельного создания.
  5. Отдельно обозначьте новый самостоятельный заказ с другим ключом и объясните, почему его нельзя считать дубликатом A17.

Как проверить результат. В модели повтор A17 не создаёт второй заказ, а новая независимая операция остаётся возможной. Тайм-аут не приравнен к отмене, принятие к завершению, а проверка состояния отделена от запуска работы.

Частые вопросы

Достаточно ли просто увеличить время ожидания?

Это может изменить частоту тайм-аутов, но не устраняет потерю ответа после успешного выполнения. Для действий с побочными эффектами всё равно нужна понятная стратегия повторов.

Можно ли применять одинаковую политику Retry ко всем запросам?

Нет. Учитываются тип ошибки, свойства операции, ограничения сервиса и допустимое время ожидания. Повторы должны быть частью явно определённого поведения системы.

Самостоятельный разбор темы. Содержание конкретной обучающей программы здесь не представлено.

Зарегистрируйтесь, чтобы уточнить возможность доступа к этому материалу

Зарегистрироваться
← К списку материалов