Вебхуки великолепны, пока ваш целевой сервер не упадет или не пропадет сетевое соединение. Вебхуки по своей природе работают по принципу «отправил и забыл» (fire and forget), но в критически важных бизнес-процессах (таких как получение платежей) «забыть» — это не вариант.
В этой статье мы рассмотрим, как сделать вашу архитектуру вебхуков более устойчивой (resilient) и как снизить потерю данных до 0%.
Сервис, отправляющий вебхук, не ждет ответа вечно. Обычно существует тайм-аут в 5-10 секунд. Если ваш endpoint не ответит в течение этого времени, запрос считается неудачным.
Решение: Никогда не выполняйте длительные операции (создание PDF, отправка писем, отчеты базы данных) на endpoint, который принимает вебхук. Единственное, что вам нужно сделать:
200 OK отправителю.Любая система может упасть. Ваш сервер может быть на обслуживании или может возникнуть мгновенная ошибка сети. В этих случаях вебхук не должен быть потерян.
Exponential Backoff: Вместо того чтобы сразу же повторять неудачный запрос, самый здоровый метод — пытаться, увеличивая время ожидания.
Обязательно изучите политику повторных попыток вашего провайдера вебхуков (например, Stripe). Также обязательно настройте стратегию повторных попыток в своих собственных отправках вебхуков.
Механизм повторных попыток великолепен, но имеет опасный побочный эффект: Один и тот же запрос приходит более одного раза.
Если ответ 200 OK не доходит до отправителя из-за ошибки сети, отправитель отправляет тот же вебхук снова. Если ваш код не готов к этому, вы можете списать с клиента плату дважды или создать дублирующиеся записи в базе данных.
Решение: В каждом запросе вебхука есть уникальный ID (Event ID). Храните этот ID в вашей базе данных или Redis.
if redis.exists(event_id) {
return 200 OK; // Уже обработано, не делать снова.
}
process_payment();
redis.save(event_id);
Поскольку ваш endpoint является публичным, злоумышленники могут отправлять поддельные запросы вебхуков. Чтобы предотвратить это, обязательно проверяйте подпись HMAC (Hash-based Message Authentication Code). Отправитель хеширует payload секретным ключом и отправляет его в заголовке. Вы выполняете ту же операцию и проверяете, совпадает ли она.
Что произойдет, если все попытки повтора не удадутся? Вместо того чтобы удалять данные, переместите их в отдельную область, называемую «Dead Letter Queue» (Очередь мертвых писем). Вы можете вручную изучить ошибочные записи здесь позже и обработать их снова после устранения проблемы.
Построение надежной архитектуры вебхуков требует управления очередями, стратегий повторных попыток и мер безопасности.
Если вы не хотите строить всю эту инфраструктуру (Queue, Retry, DLQ, Logging) с нуля, вы можете использовать Webhook Gateway, такой как WebhookIO. WebhookIO принимает все входящие запросы за вас, ставит их в очередь и безопасно доставляет вам, когда ваш endpoint готов.