Вернуться к документации
Предсказуемая повторная доставка

Повторные попытки доставки

Разберитесь, когда Adal повторяет доставку, как строится расписание попыток и как защитить приложение от повторных побочных эффектов.

Последнее обновление: 26 июля 2026 г. [email protected]
На этой странице

Обзор

Повторные попытки помогают доставить принятый вебхук, если получатель временно недоступен или завершил запрос ошибкой. Adal сохраняет результат каждой попытки и, если это предусмотрено настройками получателя, планирует следующую.

Запрос → Попытка №1 → Ошибка → Ожидание → Попытка №2 → 2xx → Доставлено

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

Повторные попытки повышают устойчивость доставки, но не гарантируют доставку ровно один раз и не исключают дубликаты. Получатель должен быть готов безопасно обработать один запрос повторно.

Что считается успешной и неуспешной попыткой

Успешная попытка

Доставка считается успешной, когда получатель возвращает любой HTTP-статус из диапазона 2xx . После такого ответа Adal не планирует для этой доставки автоматический повтор.

Успешный статус означает, что Adal получил ожидаемый HTTP-ответ. Он не подтверждает, что приложение завершило внутреннюю обработку, записало данные или выполнило бизнес-операцию.

Неуспешная попытка

Попытка считается неуспешной, если получатель вернул статус вне диапазона 2xx или запрос не удалось завершить. Например:

  • получатель вернул 4xx или 5xx ;
  • не удалось установить сетевое соединение;
  • истёк тайм-аут;
  • произошла ошибка DNS или TLS;
  • Adal CLI не смог обратиться к локальному сервису.

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

Автоматические повторные попытки

Для каждого получателя можно выбрать от 1 до 10 попыток. Выбранное значение включает первую отправку:

  • 1 попытка — одна отправка без автоматических повторов;
  • 2 попытки — первая отправка и не более одного повтора;
  • 10 попыток — первая отправка и не более девяти повторов.

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

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

Расписание повторов

После неуспешной попытки Adal рассчитывает задержку перед следующей по формуле:

задержка = n² минут

Здесь n — номер следующей попытки. Задержка отсчитывается от завершения предыдущей попытки, а не от времени приёма исходного запроса.

Следующая попытка Задержка после предыдущей
№2 4 минуты
№3 9 минут
№4 16 минут
№5 25 минут
№6 36 минут
№7 49 минут
№8 1 час 4 минуты
№9 1 час 21 минута
№10 1 час 40 минут
Общая длительность попыток 6 часов 24 минуты

Например, попытка №2 начинается через 4 минуты после завершения первой. Если она завершилась ошибкой, попытка №3 планируется ещё через 9 минут.

Расчётное время — это момент, раньше которого повтор не должен начаться. Фактическая отправка может произойти позже, например пока Adal CLI отключён или доставка временно приостановлена.

Ожидание Adal CLI

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

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

Доставка запросов, накопившихся во время отключения CLI, зависит от настройки сервера Доставлять ожидающие запросы при подключении:

  • если настройка включена, сохранённые ожидающие запросы передаются после подключения;
  • если настройка отключена, CLI получает только новые запросы, а прежние остаются в ожидании.

Если CLI подключён, но локальный сервис недоступен, начатая отправка завершается ошибкой и учитывается как использованная попытка.

Независимые доставки получателям

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

Запрос
├── Получатель A → 2xx → Доставлено
├── Получатель B → 5xx → Повтор запланирован
└── Получатель C → CLI отключён → Ожидание

Успех получателя A не отменяет повтор для получателя B. Ожидание получателя C не задерживает остальные доставки. Количество попыток настраивается отдельно для каждого получателя.

Ручной повтор, отмена и Replay

Ручной повтор доставки

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

Вручную можно повторить неуспешную, отменённую или уже успешную доставку. Каждая такая операция расходует 1 кредит.

Отмена ожидающей доставки

Доставку в статусе ожидания можно отменить. После отмены Adal не выполняет запланированную автоматическую попытку. Уже начатый HTTP-запрос отозвать нельзя; отмена также не затрагивает других получателей.

Replay запроса

Replay создаёт новый запрос на основе сохранённого и запускает обычную доставку всем получателям, настроенным для сервера на момент повторной отправки. Исходный запрос не меняется. Replay расходует 1 кредит.

Действие Результат Дополнительные кредиты
Автоматический повтор Ещё одна попытка доставки одному получателю Нет
Ручной повтор Новая доставка существующего запроса одному получателю 1 кредит
Replay Новый запрос и доставки текущим получателям 1 кредит

Дубликаты и идемпотентность

Автоматический или ручной повтор может доставить один запрос несколько раз. Replay также может повторить то же внешнее событие, но уже как новый запрос Adal. Обработчик получателя должен учитывать оба сценария.

Для каждого получателя можно включить передачу заголовка:

X-Adal-Idempotency: <ключ-запроса>

Автоматические и ручные повторы одного запроса получают то же значение ключа. При Replay создаётся новый запрос и новый ключ. Чтобы ключ защищал от повторного действия, приложение должно сохранять уже обработанные значения и не выполнять операцию для известного ключа.

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

  • проверяйте подпись отправителя до обработки;
  • валидируйте входные данные;
  • делайте обработчик идемпотентным;
  • фиксируйте стабильный идентификатор события атомарно с бизнес-операцией;
  • возвращайте 2xx только после принятия ответственности за обработку.

Заголовок X-Adal-Idempotency не превращает доставку в «ровно один раз». Дедупликацию и безопасную обработку повторов реализует получатель.

История доставки

Откройте принятый запрос в панели Adal, чтобы просмотреть доставки, сгруппированные по получателям. Для каждой попытки доступны технические сведения, в том числе:

  • получатель и способ доставки;
  • номер попытки;
  • дата и время выполнения;
  • текущий статус;
  • HTTP-статус ответа, если он получен;
  • время выполнения запроса;
  • сообщение о сетевой, DNS-, TLS- или другой ошибке.

Статус ожидания означает, что отправка ещё не началась. Такая запись не расходует попытку, пока Adal не начал доставку.

Adal не хранит заголовки и тело ответа получателя. История показывает статус, время и диагностические сведения, но не полное содержимое ответа.

Ограничения и жизненный цикл

  • автоматические повторы выполняются только в пределах выбранного количества попыток;
  • ожидающая доставка зависит от срока хранения исходного запроса;
  • после удаления данных запроса повторить или воспроизвести его нельзя;
  • удаление сервера останавливает приём, удаляет получателей и отменяет ожидающие доставки;
  • ручной повтор и Replay могут создать повторные побочные эффекты в целевом приложении.

Срок хранения определяется тарифом и настройками сервера. После его окончания Adal безвозвратно удаляет запрос вместе с историей и записями попыток доставки.

Повторы не заменяют очередь, журнал операций, мониторинг или механизм восстановления в вашем приложении. Отслеживайте бизнес-результат после получения запроса самостоятельно.

Устранение неполадок

Повтор не запланирован

Убедитесь, что получатель не вернул 2xx а выбранное количество попыток больше номера уже завершившейся попытки. Если настроена одна попытка, автоматического повтора не будет.

Попытка долго остаётся в ожидании

Для доставки через Adal CLI проверьте соединение CLI и настройку сервера Доставлять ожидающие запросы при подключении. Для Direct HTTP проверьте рассчитанное время следующей попытки и историю доставки.

Получатель обработал событие дважды

Проверьте, сохраняет ли приложение idempotency key или стабильный идентификатор события до выполнения необратимого действия. Учитывайте тайм-ауты: предыдущая попытка могла завершить бизнес-операцию, даже если Adal не получил ответ.

В Adal показан успех, но операция не выполнена

Проверьте журналы и состояние целевого приложения. Статус доставки подтверждает HTTP-ответ 2xx а не итог внутренней бизнес-операции.

  • Получатели — настройка Direct HTTP, Adal CLI, количества попыток и idempotency key.
  • Серверы — приём запросов, кредиты, доставка ожидающих запросов и Replay.
  • Adal CLI — подключение локального приложения и диагностика доставки.
  • Хранение данных — сроки хранения запросов и истории доставки.
  • Тарифы и ограничения — актуальные лимиты и кредиты.