Очереди, retry и DLQ: как не терять заявки в автоматизации
Чтобы не терять заявки в автоматизации, нужен не «ещё один webhook в Make», а контур из очереди, идемпотентного worker, retry с backoff, DLQ и явной эскалации человеку — иначе сбой CRM в пятницу вечером съедает лиды молча.
Я проектирую pipeline от входящего события до результата так, будто интеграции будут падать: таймауты, 429, частичные ответы, дубли. Ниже — рабочая схема, метрики и правила, которые удерживают поток заявок в МСП без героизма дежурного.
Каркас pipeline: от события до результата
Минимальный боевой контур я собираю из пяти узлов. Пропуск любого из них почти гарантирует «заявка зависла / уехала дважды».
| Узел | Ответственность | Типичный failure mode |
|---|---|---|
| Ingress | Приём webhook/form/почты, проверка подписи | Подделка, ретраи провайдера |
| Queue | Буфер, приоритет, delayed retry | Переполнение, poison message |
| Worker | Бизнес-шаг + вызовы API | Таймаут, 5xx, кривая схема |
| Outbox / state | Статус заявки в своей БД/CRM | Рассинхрон «сделали, но не записали» |
| Notify | Клиент / менеджер / DLQ-алерт | Тихий провал уведомлений |
Чеклист на старте пилота
- У каждого события есть stable id (или hash тела + source).
- Worker идемпотентен: повтор с тем же id не создаёт вторую сделку.
- Статусы заявки живут у вас, а не только в UI стороннего SaaS.
- Есть видимая очередь отложенных и DLQ (хотя бы таблица + дашборд).
- Алерт человеку при DLQ > 0 за N минут — не «потом в логах посмотрим».
Без идемпотентности retry опаснее, чем отсутствие retry: вы чините доступность ценой дублей в CRM.
Retry: когда повторять, а когда сразу в DLQ
Слепой retry «ещё 10 раз сразу» усугубляет инцидент. Я разделяю ошибки на классы.
| Класс ошибки | Пример | Политика |
|---|---|---|
| Transient | 502, timeout, connection reset | Retry + exponential backoff + jitter |
| Rate limit | 429, Retry-After | Delayed retry по заголовку |
| Business reject | 400 validation, «сделка закрыта» | Без retry → fix data or escalate |
| Auth | 401/403 после ротации ключа | Stop + page on-call, не молотить |
| Poison | Падает на любом payload | 1–2 попытки → DLQ + sample |
Практичные числа для МСП (старт)
- max attempts: 5 для transient;
- backoff: 30s → 2m → 10m → 30m → 2h (с jitter ±20%);
- отдельный fast-fail для auth и schema errors;
- deadline на жизнь сообщения: 24–72 ч, потом DLQ + ручной разбор;
- concurrent workers: ограничить, чтобы не убить CRM rate limit.
Правило: retry только если повтор безопасен. Создание платежа/отправка SMS без idempotency key — не retry, а ручной или компенсирующий сценарий.
DLQ и эскалация человеку: пакет, а не «ошибка в логе»
Dead Letter Queue — не помойка, а очередь работы для людей. Я кладу туда достаточно контекста, чтобы менеджер или интегратор закрыл кейс без археологии.
| Поле DLQ-записи | Зачем |
|---|---|
| original_event_id | Связь с источником |
| last_error_code / message | Быстрый triage |
| attempt_count + timestamps | Понять «долго молотили» |
| payload_redacted | Воспроизведение без секретов |
| suggested_owner | sales / ops / eng |
| customer_impact | lead lost / delay / unknown |
| replay_safe | yes/no — можно ли кнопкой replay |
Эскалация: три уровня
- L1 авто: клиенту «принялии, свяжемся»; менеджеру карточка «нужен ручной шаг».
- L2 ops: DLQ > порога или auth failure — алерт в чат дежурного.
- L3 eng: poison rate, рост latency p95, circuit open > 15 мин.
Эскалация без suggested_owner и impact превращается в общий шум: все видят, никто не берёт.
Метрики, без которых pipeline «вроде работает»
Я смотрю не «количество сценариев в no-code», а воронку доставки.
| Метрика | Нормальный смысл | Красный флаг |
|---|---|---|
| Ingress → queued | Приём жив | Падение при росте маркетинга |
| Success rate 24h | Доля доведённых | < 95% на критичном потоке |
| p95 processing time | Скорость до результата | Скачок после релиза |
| Retry rate | Доля с ≥1 retry | Рост = деградация API |
| DLQ rate | Доля в ручной разбор | > 2–3% — чинить корень |
| Duplicate suppress | Сколько отсекли | Внезапно 0 — сломан id |
| Human escalate rate | Доля handoff | Рост без роста quality |
Мини-ритуал на неделю
- Топ-5 ошибок в DLQ — одна корневая причина в спринт.
- Один «сухой» replay учебного события end-to-end.
- Проверка, что алерт DLQ реально будит нужный чат (не /dev/null).
- Сверка: число лидов в рекламе ≈ ingress ≈ созданных карточек (±допуск).
Если сверка расходится, я не «улучшаю промпт агента» — сначала чиню трубу.
Часто задаваемые вопросы
Хватает ли встроенных retry в Zapier/Make?
Для низкого объёма — иногда. Для лидов и оплат мне нужны свои статусы, идемпотентность и DLQ с владельцем. Иначе разбор инцидента — скриншоты из пяти UI.
Что делать с уже попавшими в DLQ заявками?
Сортировка по impact → replay_safe=yes пачкой после фикса → остальные вручную с шаблоном ответа клиенту. Не replay всего слепо.
Как не задушить CRM ретраями?
Общий rate limiter на connector, bulkhead по типу события, backoff с jitter, circuit breaker на 5xx.
Нужна ли очередь, если событий мало?
Да, хотя бы лёгкая (таблица + worker по cron): она даёт отложенный retry и DLQ. Прямой «webhook → 8 HTTP» хрупкий даже на 20 лидах/день.
Читайте также
- Pipeline от заявки до результата: интеграции, сбои, эскалация
- Оркестрация tool-calling AI-агента: SOP, лимиты и audit trail
- TCO и ROI AI в бою: что ломается и как считать за 90 дней
Нужен разбор вашего контура заявок и схема очередей/DLQ под CRM — напишите: https://raisovich.ru
Чем идемпотентный worker отличается от обычного webhook-сценария?
Повтор с тем же stable id не создаёт вторую сделку: статус живёт у вас, а retry безопасен. Без идемпотентности retry опаснее отсутствия retry.
Когда ошибку нельзя ретраить и нужно сразу в DLQ?
Business reject (400, закрытая сделка), auth 401/403 и poison payload — без слепого retry; в DLQ кладут context, owner и replay_safe для человека.
Какие метрики pipeline заявок смотреть ежедневно?
Success rate 24h, DLQ rate, duplicate suppress и сверку ads → ingress → карточки CRM: расхождение чинят в трубе, а не «улучшением промпта».
Подпишитесь на @raisovich_news
Первыми получайте новые статьи об AI-автоматизации, нейросетях для бизнеса и создании сайтов. Без спама — только полезный контент.
Часто задаваемые вопросы
Чем идемпотентный worker отличается от обычного webhook-сценария?
Повтор с тем же stable id не создаёт вторую сделку: статус живёт у вас, а retry безопасен. Без идемпотентности retry опаснее отсутствия retry.
Когда ошибку нельзя ретраить и нужно сразу в DLQ?
Business reject (400, закрытая сделка), auth 401/403 и poison payload — без слепого retry; в DLQ кладут context, owner и replay_safe для человека.