Тимур ТурдыевНаписать

статья · 2026-10-11

Очередь перед чужим API

Почему между вебхуком и внешней CRM всегда стоит очередь, и какие три вещи делают её надёжной.

LaravelRabbitMQинтеграции

Проблема ​

Облачная АТС присылает вебхук о звонке и ждёт ответ две секунды. CRM, куда этот звонок надо записать, отвечает до пяти секунд, а иногда отдаёт 500 без тела. Если ходить в CRM прямо из обработчика вебхука, часть звонков теряется: АТС не дождалась ответа, CRM упала, событие пропало.

Решение: принять быстро, обработать потом ​

Контроллер делает минимум: проверяет подпись и кладёт событие в очередь. Ответ уходит за миллисекунды, а медленная работа достаётся воркеру.

php
public function __invoke(Request $request): Response
{
    $this->signature->verify($request);

    $this->bus->publish('calls', CallEvent::fromWebhook($request->all()));

    return response()->noContent();
}

Три вещи, без которых очередь не спасает ​

Идемпотентность ​

АТС при нестабильной связи присылает один и тот же вебхук несколько раз. Ключ идемпотентности по call_id превращает повтор в пустую операцию.

php
if (! $this->processed->claim($event->callId)) {
    return; // уже обработан
}

Повтор с паузой ​

Если CRM ответила ошибкой, сообщение возвращается в очередь. Пауза растёт: 2, 4, 8 секунд. Три попытки, потом сообщение уходит в отдельную очередь для разбора руками.

Наблюдаемость ​

Каждое событие логируется с итогом: создана задача, создан лид, отложено. Без этого очередь превращается в чёрный ящик, где «что-то иногда теряется».

Что получилось ​

Так же устроены вебхуки телеметрии в Waviot, которые я довожу: сообщения приборов лежат в durable-очереди RabbitMQ, обработчик держит heartbeat, а сбой базы или брокера переживается повторами, а не потерей событий.

© 2014-2026 Тимур ТурдыевСайт и справочник работают на VPS от AdminVPS