Dead Letter Queue. Как обрабатывать битые сообщения в RabbitMQ и Kafka

9 минут чтения
Средний рейтинг статьи — 4.8

Очереди сообщений помогают строить отказоустойчивые распределённые системы. Однако в любой системе рано или поздно появляются сообщения, которые невозможно обработать.

Например:

  • некорректный JSON
  • удалённый пользователь, на которого ссылается событие
  • ошибка бизнес-логики
  • несовместимость версий сервисов
  • временно недоступная база данных

Если такие сообщения обрабатывать неправильно, они могут блокировать очередь, создавать бесконечные ретраи или приводить к потере данных.

Для решения этой проблемы используются Dead Letter Queue (DLQ).

Что такое Dead Letter Queue

Dead Letter Queue — это специальная очередь для сообщений, которые не удалось успешно обработать.

Вместо того чтобы бесконечно пытаться обработать проблемное сообщение, система переносит его в отдельное хранилище для дальнейшего анализа.

Схема выглядит примерно так:

Producer

Main Queue

Consumer

Ошибка

Dead Letter Queue

Основная очередь продолжает работать, а проблемные сообщения не мешают обработке остальных данных.

Почему нельзя просто повторять обработку бесконечно

На первый взгляд кажется логичным постоянно выполнять retry.

Но на практике это быстро приводит к проблемам.

Представим сообщение:

{
  "userId": 123,
  "email": "invalid-email"
}

Если код обработки всегда падает на этом сообщении, повторная попытка ничего не изменит.

В результате получаем:

Ошибка
Retry
Ошибка
Retry
Ошибка
Retry
...

Такое сообщение может годами крутиться в очереди, создавая нагрузку и засоряя логи.

Поэтому обычно задают максимальное количество попыток обработки.

После превышения лимита сообщение отправляется в DLQ.

Какие ошибки стоит отправлять в DLQ

Не каждая ошибка должна приводить к попаданию сообщения в dead letter queue.

Полезно разделять ошибки на две категории.

Временные ошибки:

  • недоступность БД
  • сетевые проблемы
  • перегрузка сервиса
  • временный timeout

Для таких случаев retry обычно помогает.

Постоянные ошибки:

  • битый JSON
  • отсутствующее обязательное поле
  • нарушение схемы данных
  • ошибка бизнес-валидации

Здесь повторная обработка бессмысленна.

Именно такие сообщения чаще всего оказываются в DLQ.

Как работает DLQ в RabbitMQ

В RabbitMQ механизм реализован через Dead Letter Exchange.

Основная очередь настраивается так, чтобы отклонённые сообщения автоматически перенаправлялись в специальную очередь.

Упрощённая схема:

Main Queue

Reject

Dead Letter Exchange

Dead Letter Queue

Сообщение может попасть туда по нескольким причинам:

  • consumer сделал reject
  • превышен TTL
  • превышен лимит длины очереди
  • сообщение несколько раз не прошло обработку

После этого его можно анализировать отдельно от основного потока.

Как работает DLQ в Kafka

В Kafka отдельного встроенного механизма DLQ нет.

Обычно создаётся специальный топик:

orders
orders-dlq

Если consumer не смог обработать событие после нескольких попыток, он публикует его в DLQ-топик.

При этом обычно сохраняют:

  • исходное сообщение
  • текст ошибки
  • стек исключения
  • время возникновения проблемы

Это значительно упрощает расследование инцидентов.

Что хранить в DLQ

Частая ошибка — складывать только исходное сообщение.

Через несколько дней разобраться в причине становится сложно.

Полезно сохранять дополнительные данные:

{
  "payload": {...},
  "error": "Validation failed",
  "service": "billing",
  "attempts": 5,
  "timestamp": "2026-06-03T12:00:00Z"
}

Так инженеры сразу понимают, что произошло и где искать проблему.

Нужно ли мониторить DLQ

Обязательно.

Само существование DLQ не решает проблему.

Если никто не следит за содержимым очереди, сообщения просто будут накапливаться.

Поэтому обычно отслеживают:

  • количество сообщений в DLQ
  • скорость роста DLQ
  • число новых сообщений за период
  • самые частые ошибки
  • возраст старейшего сообщения

Резкий рост DLQ часто становится первым признаком проблем после релиза.

Что делать с сообщениями из DLQ

После попадания в DLQ есть несколько вариантов.

Первый — исправить данные и повторно отправить сообщение в основную очередь.

Второй — исправить ошибку в коде и выполнить replay всех сообщений.

Третий — признать данные некорректными и удалить их.

Выбор зависит от характера проблемы и требований бизнеса.

Опасность автоматического replay

Многие команды делают кнопку «Вернуть всё обратно в очередь».

Это удобно, но опасно.

Если причина ошибки не устранена, происходит следующее:

Main Queue

DLQ

Replay

Main Queue

DLQ

Получается бесконечный цикл.

Поэтому replay должен выполняться только после анализа причины сбоя.

Типичные причины роста DLQ

На практике чаще всего встречаются:

  • изменение схемы сообщений
  • ошибки сериализации
  • несовместимость версий сервисов
  • баги после релиза
  • удалённые данные в БД
  • ошибки миграций

Во многих случаях всплеск DLQ позволяет обнаружить проблему раньше, чем пользователи начнут массово жаловаться.

Хорошие практики работы с DLQ

Полезно придерживаться нескольких правил:

  • ограничивать число retry
  • сохранять информацию об ошибке
  • мониторить размер DLQ
  • настраивать алерты на рост сообщений
  • регулярно анализировать содержимое очереди
  • иметь безопасный механизм replay

DLQ должна рассматриваться как инструмент диагностики, а не как место для бесконечного хранения проблемных событий.

Итоги

Dead Letter Queue позволяет изолировать сообщения, которые невозможно успешно обработать.

Без DLQ битые события способны создавать бесконечные ретраи, перегружать систему и мешать обработке нормальных данных.

В RabbitMQ для этого используется Dead Letter Exchange, а в Kafka обычно создают отдельный DLQ-топик.

Грамотно настроенная DLQ помогает быстро находить ошибки интеграции, безопасно обрабатывать сбои и поддерживать стабильность распределённой системы даже при появлении некорректных сообщений.

9 минут чтения
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний