Ответ
Dead Letter Queue (DLQ) — это специальная очередь в системах обмена сообщениями (например, RabbitMQ, Kafka), предназначенная для хранения сообщений, которые не могут быть успешно обработаны основной очередью.
Основная цель — изолировать «проблемные» сообщения, чтобы они не блокировали обработку других сообщений и не терялись безвозвратно. Это позволяет разработчикам и системным администраторам анализировать ошибки и принимать решения о дальнейшей судьбе таких сообщений (например, исправить и переотправить или удалить).
Основные причины попадания сообщения в DLQ:
- Ошибка обработки: Обработчик (consumer) явно отклоняет сообщение (например, с помощью
NACK
в RabbitMQ), потому что не может его обработать (например, из-за неверного формата данных или временной недоступности внешнего сервиса). - Истечение TTL (Time-To-Live): Сообщение находилось в очереди дольше установленного времени жизни.
- Превышение длины очереди: Основная очередь достигла максимального количества сообщений.
Как это работает (на примере RabbitMQ):
- Создается основная очередь (
work-queue
) и настраивается так, чтобы при невозможности обработки она перенаправляла сообщения в специальный обменник (dlx-exchange
). - Создается очередь для «мертвых» писем (
dlq-queue
). dlq-queue
привязывается кdlx-exchange
.
Пример обработчика на Go, который может отправить сообщение в DLQ:
// ... код подключения к RabbitMQ ...
msgs, err := ch.Consume(
"work-queue", // Название основной очереди
"", // consumer
false, // auto-ack = false, ручное подтверждение
false,
false,
false,
nil,
)
for msg := range msgs {
log.Printf("Получено сообщение: %s", msg.Body)
// Пытаемся обработать сообщение
if err := processMessage(msg.Body); err != nil {
log.Printf("Ошибка обработки: %v. Отправляем в DLQ.", err)
// Отклоняем сообщение (requeue=false), чтобы оно ушло в DLQ,
// а не вернулось в исходную очередь.
msg.Nack(false, false)
} else {
// Сообщение успешно обработано
msg.Ack(false)
}
}