Перейти к содержанию

Retry и DLQ в n8n: безопасные HTTP-запросы без потерь и дублей

Обновлено: 2026-05-30

AI summary: Практический workflow для устойчивых HTTP-интеграций: принять событие, собрать idempotency key, отправить запрос во внешний API, классифицировать ответ, повторить временные ошибки с backoff, а необработанные события положить в DLQ с понятным alert.
Шаблон для внедрения

Импортируйте workflow, замените credentials и прогоните тестовый payload до включения production.

Проблема: внешний API может вернуть 429, 502 или timeout именно в момент, когда заявка уже принята бизнесом. Если n8n просто падает на HTTP Request, событие теряется или вручную перезапускается с риском дубля.

Решение: строим retry/DLQ-слой в n8n: отделяем временные ошибки от постоянных, добавляем backoff, сохраняем payload и idempotency key, отправляем alert владельцу и даём команде безопасный способ переиграть событие.

Схема retry и DLQ для HTTP Request в n8n
Workflow отправляет HTTP Request, классифицирует ответ, повторяет 429/5xx и сохраняет необработанные события в DLQ.

Проблема: почему HTTP Request в n8n теряет события при 429 и 5xx

Типичная интеграция выглядит безобидно: Webhook принимает заявку, HTTP Request отправляет её в CRM или склад, а дальше workflow завершается. Но production живёт иначе: API ограничивает частоту запросов, прокси рвёт соединение, токен истекает, а downstream-сервис отвечает 502 после того, как часть операции уже выполнена.

Без retry и DLQ команда не понимает, какие события действительно обработаны, какие можно повторить, а какие нужно исправлять вручную. Эта статья решает конкретную боль интеграторов: как сделать HTTP Request в n8n устойчивым к временным сбоям и при этом не создать дубли при повторной отправке.

Архитектура workflow retry/DLQ для HTTP-интеграции

НодаРольЧто проверить
Webhook or Triggerполучает бизнес-событиеevent_id, source, payload, дедупликационный ключ
Prepare API requestсобирает endpoint, headers и bodyнет секретов в тексте execution, timeout задан явно
HTTP Requestотправляет запрос во внешний APIresponse code, response body, retryable network errors
Classify responseразделяет success, retry и DLQ429/5xx/timeout не смешаны с 400/422
Retry with backoffповторяет временные ошибкиattempt_count, next_retry_at, max attempts
Dead-letter queueсохраняет необработанное событиеpayload, причина, владелец, ссылка на execution

Главная SEO-и практическая разница между “retry” и “просто перезапустить workflow” — наличие контекста. В DLQ должен лежать исходный payload, статус API, число попыток, idempotency key и понятная причина, чтобы повтор был безопасным.

Контракт входных данных для API-запроса

{
  "event_id": "lead-10492",
  "source": "landing-webhook",
  "target": "crm-api",
  "idempotency_key": "landing:lead-10492",
  "customer": {
    "name": "Мария",
    "phone": "+7 (916) 555-12-34"
  },
  "request": {
    "method": "POST",
    "url": "https://api.example.ru/leads",
    "body": {
      "name": "Мария",
      "phone": "+79165551234"
    }
  },
  "attempt": 1
}

`event_id` и `idempotency_key` обязательны. Если внешний API поддерживает заголовок `Idempotency-Key`, передавайте туда тот же ключ. Если не поддерживает — храните ключ в Postgres и не повторяйте бизнес-действие вслепую.

Code Node: классификация ответа, retry и DLQ route

const src = $json.body ?? $json;
const status = Number(src.http_status ?? src.statusCode ?? 0);
const attempt = Number(src.attempt ?? 1);
const maxAttempts = Number(src.max_attempts ?? 5);
const idempotencyKey = String(src.idempotency_key ?? src.event_id ?? '').trim();

if (!idempotencyKey) throw new Error('Missing idempotency_key for retry workflow');

const retryableStatus = [408, 409, 425, 429, 500, 502, 503, 504];
const isNetworkError = String(src.error ?? '').toLowerCase().includes('timeout');
const retryable = retryableStatus.includes(status) || isNetworkError;
const permanentFailure = status >= 400 && status < 500 && !retryable;
const delaySeconds = Math.min(900, Math.pow(2, attempt) * 15);

let route = 'success';
if (retryable && attempt < maxAttempts) route = 'retry';
if (retryable && attempt >= maxAttempts) route = 'dlq';
if (permanentFailure) route = 'dlq';

return [{
  json: {
    route,
    idempotency_key: idempotencyKey,
    attempt,
    max_attempts: maxAttempts,
    next_attempt: attempt + 1,
    retry_after_seconds: delaySeconds,
    status,
    reason: src.error ?? src.response?.message ?? 'classified_by_retry_policy',
    original_payload: src.original_payload ?? src
  }
}];
Почему 400 и 500 нельзя обрабатывать одинаково

400/422 обычно означают ошибку данных и должны уходить в DLQ с описанием. 429/502/503 чаще временные: их можно повторять с backoff, но только с idempotency key и лимитом попыток.

Готовый workflow JSON: скачать и импортировать

Скачать готовый workflow JSON Скачать тестовый payload

{
  "name": "Nodbot - HTTP Request retry and DLQ policy",
  "nodes": [
    {
      "name": "Webhook input",
      "type": "n8n-nodes-base.webhook",
      "purpose": "Принять событие и idempotency key"
    },
    {
      "name": "Prepare HTTP request",
      "type": "n8n-nodes-base.code",
      "purpose": "Собрать endpoint, headers, body и timeout"
    },
    {
      "name": "Send HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Отправить запрос во внешний API"
    },
    {
      "name": "Classify API response",
      "type": "n8n-nodes-base.code",
      "purpose": "Разделить success/retry/DLQ"
    },
    {
      "name": "Retry gate",
      "type": "n8n-nodes-base.if",
      "purpose": "Проверить лимит попыток и статус"
    },
    {
      "name": "Write DLQ record",
      "type": "n8n-nodes-base.postgres",
      "purpose": "Сохранить payload, reason и execution URL"
    },
    {
      "name": "Respond",
      "type": "n8n-nodes-base.respondToWebhook",
      "purpose": "Вернуть безопасный результат"
    }
  ],
  "connections": "Webhook input → Prepare HTTP request → Send HTTP Request → Classify API response → Retry gate → Write DLQ record → Respond"
}

Пошаговая настройка retry, backoff и DLQ в n8n

  1. Импортируйте workflow и замените endpoint внешнего API.
  2. Добавьте idempotency key в payload и, если API поддерживает, в header `Idempotency-Key`.
  3. Создайте таблицу DLQ с полями idempotency_key, payload, reason, attempt, status.
  4. Настройте retry policy: 429/5xx/timeout повторять, 400/422 отправлять в DLQ.
  5. Добавьте Telegram/Slack alert только после записи DLQ, чтобы не потерять контекст.

Тесты перед production и проверка повторов

curl -X POST "https://YOUR-N8N-DOMAIN/webhook/retry-dlq-http-request" \
  -H "Content-Type: application/json" \
  --data @retry-dlq-http-request-payload.json
  1. Сымитируйте 200 OK и проверьте, что запись не попадает в DLQ.
  2. Сымитируйте 429 и убедитесь, что route = retry, а delay растёт.
  3. Сымитируйте 422 и проверьте route = dlq без повторов.
  4. Запустите один и тот же event_id дважды и проверьте idempotency.
  5. Отключите внешний API и убедитесь, что после max_attempts событие попадает в DLQ.

Production-риски retry и dead-letter queue

  • Retry без idempotency. Повтор может создать вторую сделку, списание или заявку.
  • Бесконечные повторы. Workflow забивает очередь и маскирует настоящую ошибку данных.
  • DLQ без payload. Нельзя безопасно восстановить событие после инцидента.
  • Alert до записи DLQ. Уведомление пришло, но контекст потерян при сбое.
  • Все ошибки считаются временными. 400/422 будут повторяться зря и увеличивать нагрузку.

См. также webhook idempotency to Postgres, Error Workflow → Telegram alert, retry/DLQ pattern и ЮKassa → CRM с idempotency. Официальные документы: n8n HTTP Request node, n8n error handling и HTTP status codes.

Карточка результата retry и DLQ в n8n
Визуальная карточка показывает route, attempt, статус API и следующий шаг обработки.

Критерии готовности

  1. Retryable-статусы отделены от ошибок данных.
  2. Каждый повтор использует idempotency key.
  3. DLQ хранит исходный payload, reason, status и attempt_count.
  4. Есть лимит попыток и понятный backoff.
  5. Команда знает, как безопасно переиграть DLQ-событие.
Нужно, чтобы API-интеграции не теряли события?

Nodbot настроит retry/DLQ-слой в n8n: классификацию ошибок, idempotency, журнал восстановления, alert и безопасные повторы.

Настроить надежный HTTP workflow