Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як надійно доставляти вихідні вебхуки: повтори, затримки й журнал доставок?

Одержувач вебхука може бути недоступним, повільним чи повертати помилку - доставка мусить це пережити.

Архітектура відправлення:

  1. подія фіксується в базі в тій самій транзакції, що й зміна даних (запис «вебхук до відправки»). Інакше при падінні після коміту подія загубиться - патерн outbox;
  2. джоба в черзі надсилає запит;
  3. результат кожної спроби записується в журнал доставок.
final class DeliverWebhook implements ShouldQueue
{
    public $tries = 8;

    public function __construct(public WebhookDelivery $delivery) {}

    public function backoff(): array
    {
        return [10, 60, 300, 1800, 3600, 7200, 21600];   // секунди: до кількох годин
    }

    public function handle(): void
    {
        $response = Http::timeout(5)
            ->withHeaders($this->delivery->signatureHeaders())
            ->post($this->delivery->endpoint->url, $this->delivery->payload);

        $this->delivery->recordAttempt($response->status());

        if ($response->failed()) {
            throw new WebhookDeliveryFailed($response->status());
        }
    }
}

Правила повторів:

  • наростаюча затримка (експоненційна, з випадковим розкидом) - щоб не «добити» сервер одержувача, який відновлюється, і щоб тисячі вебхуків не повторювалися синхронно;
  • повторювати мережеві помилки, тайм-аути, 5xx і 429 (з урахуванням Retry-After); 4xx на кшталт 400, 404, 410 - зазвичай ні: повтор не допоможе;
  • загальний горизонт - години чи дні (Stripe повторює до трьох днів), після чого доставка позначається невдалою.

Журнал доставок у кабінеті клієнта: подія, URL, час, код відповіді, фрагмент тіла відповіді, кількість спроб, кнопка «надіслати повторно». Найкорисніша функція для підтримки - більшість звернень «вебхук не прийшов» вирішуються переглядом журналу.

Захист від «мертвих» одержувачів: якщо ендпойнт падає днями, його автоматично вимикають і повідомляють власника листом - інакше черга забивається безнадійними спробами.

Ізоляція: вебхуки - в окремій черзі з власними воркерами, щоб повільні одержувачі не затримували решту фонових задач застосунку.

Готові інструменти: spatie/laravel-webhook-server (черга, підпис, повтори, події WebhookCallFailedEvent), або зовнішні сервіси доставки вебхуків, якщо обсяги великі.

Важливо для одержувачів: доставка «щонайменше один раз» означає дублікати - документуйте, що обробка має бути ідемпотентною за id події.

Докладніше в документації: Stripe: автоматичні повтори вебхуків

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання