Ретраи и сбои

Если приёмник не ответил 2xx, доставка повторяется по фиксированному расписанию. Если он не отвечает почти сутки — вебхук отключается, а владельцу уходит письмо.

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

Попытка Когда
1 сразу после события
2 +5 секунд
3 +5 минут
4 +30 минут
5 +2 часа
6 +5 часов
7 +10 часов
8 +10 часов

Всего 8 попыток за ~28 часов. К каждой паузе добавляется случайный джиттер ±10 %: без него тысяча событий одной транзакции била бы в ваш сервер синхронно — ровно в тот момент, когда он и так лежит.

Диспетчер просыпается раз в минуту. Одиночное изменение доезжает в пределах минуты, массовая операция (применение черновика, удаление сотрудника навсегда) — пачкой, в пределах ~15 минут: за один заход в очередь с одного эндпоинта берётся не больше 50 доставок, чтобы один шумный приёмник не занял всю партию. Заходов в минутном тике несколько — партия за партией, пока хватает бюджета тика (50 секунд).

Номер текущей попытки виден в заголовке Smengo-Delivery-Id — после двоеточия.

Классификация ответа

Ответ приёмника Что делаем
2xx успех, тело ответа игнорируется
3xx провал redirect_not_allowed: редиректы не переходим — адрес должен обслуживаться конечным сервером
410 Gone терминально: доставка помечается мёртвой, эндпоинт сразу отключается
429, 5xx провал с повтором; учитывается заголовок Retry-After
прочие 4xx провал с повтором
нет ответа за 15 секунд провал timeout с повтором
сеть, TLS, DNS провал с повтором (network_…, dns_failed)
адрес резолвится в приватную сеть провал private_address — запрос не отправляется вовсе

Retry-After

Заголовок понимается в обеих формах RFC 9110 — секунды и HTTP-дата — и применяется как max(расписание, Retry-After) с капом в 1 час. Два следствия:

  • сервер может отложить следующую попытку, но не может ускорить её: Retry-After: 0 не превращает ретраи в горячий цикл;
  • дальше часа отложить нельзя — иначе исчерпание попыток растянулось бы на недели.

Авто-отключение

Триггер — первая доставка, исчерпавшая все 8 попыток (или ответ 410 Gone). Тогда:

  1. Эндпоинт переводится в состояние «отключён» — доставки прекращаются.
  2. Все накопившиеся доставки этого эндпоинта помечаются мёртвыми и не будут отправлены после включения: иначе на починенный сервер обрушился бы 28-часовой бэклог.
  3. Владельцу уходит письмо (на платёжный адрес организации, иначе — на адрес создателя эндпоинта).
  4. В карточке вебхука появляется баннер с причиной — он виден и без письма.

Как вернуть доставку: почините приёмник → «Отправить тестовое» → убедитесь, что пришёл 2xx → включите вебхук обратно. Пропущенное за время отключения дочитывается через API v1 — ручного повтора доставок в v1 нет.

Пауза, а не отключение

Кнопка «Пауза» — не то же самое, что авто-отключение:

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

Неактивная подписка

Если у организации кончился триал и подписка неактивна, push останавливается вместе с остальным платным функционалом: доставка откладывается на час и повторяется, попытка при этом не расходуется, эндпоинт не отключается. После оплаты доставки возобновятся сами, в пределах часа. В журнале такие строки помечены subscription_inactive.

Журнал доставок

  • Хранится 30 дней, вместе с телом события — ровно тем, что ушло на ваш адрес.
  • Ниже карточек, в блоке «Последние доставки», видны 25 последних доставок по всем вебхукам организации: время, тип события, код ответа, число попыток, тело и история попыток. Лимит общий: при трёх эндпоинтах это 25 строк на всех, а не по 25 на каждый.
  • Из ответа сохраняются первые 512 байт — этого достаточно, чтобы увидеть текст ошибки вашего сервера.

Коды в колонке «ошибка»

Код Значение
http_<код> сервер ответил не-2xx (например, http_500)
redirect_not_allowed ответ 3xx; редиректы не поддерживаются
gone ответ 410; эндпоинт отключён
timeout ответа не было 15 секунд
network_<код> сетевая ошибка Node (network_ECONNREFUSED, network_EPROTO, …)
dns_failed имя хоста не разрешилось за отведённое время
private_address адрес резолвится в приватный или служебный диапазон
not_https, port_not_allowed, userinfo_not_allowed, fragment_not_allowed, invalid_url, url_too_long, url_too_short адрес не прошёл проверку формы перед отправкой
subscription_inactive подписка организации неактивна, доставка отложена на час
endpoint_disabled доставка погашена при авто-отключении эндпоинта
lease_expired доставка зависла (сбой инвокации) и была подобрана служебным процессом

Как не попасть на ретраи

  • Отвечайте 2xx до тяжёлой работы: примите событие, проверьте подпись, положите в очередь, ответьте 200.
  • Не отвечайте 3xx: балансировщик, который редиректит httphttps или /hook/hook/, ломает доставку. Указывайте конечный адрес.
  • Возвращайте 410 только когда адрес мёртв окончательно: этот код отключает вебхук с первого раза.
  • При временной перегрузке отвечайте 429 или 503 с Retry-After — так вы управляете темпом, не теряя событий.

Что дальше

Была ли статья полезна?