Куда отправляется уведомление об ошибке при некорректной обработке сообщения в Kafka?
Что проверяют
Понимаете ли вы, что брокер Kafka ничего не знает об ошибках обработки: для него сообщение доставлено, а что с ним сделал консьюмер, решает сам консьюмер. Следом спрашивают, как бы вы протестировали сценарий с битым сообщением.
Как отвечать
Сразу поправьте формулировку: Kafka сама уведомлений не отправляет, и встроенной очереди «мёртвых писем» у неё нет, в отличие от dead letter exchange в RabbitMQ. Куда уйдёт ошибка, определяет код или конфигурация потребителя. Типичные варианты:
- DLT (dead letter topic): отдельный топик для сообщений, которые не удалось обработать. В Spring Kafka это
DefaultErrorHandlerсDeadLetterPublishingRecoverer, по умолчанию он пишет в топик с суффиксом.DLT. В заголовки кладётся причина: исходный топик, партиция, offset, текст исключения; - retry-топики: перед DLT сообщение проходит несколько повторов с задержкой, в Spring это аннотация
@RetryableTopic; - Kafka Connect: параметры
errors.tolerance=allиerrors.deadletterqueue.topic.name; - логи и мониторинг: ошибка пишется в лог, растут метрики ошибок и consumer lag, алерт уходит в мессенджер через Alertmanager.
Как тестировать: отправить в топик заведомо битое сообщение (невалидный JSON, нарушение схемы, неизвестное значение enum) через Kafka UI, Offset Explorer или kcat. Затем проверить, что оно оказалось в DLT с правильными заголовками, что консьюмер продолжил читать следующие сообщения, что offset закоммичен и сработал алерт. Отдельно проверить временную ошибку, например недоступность базы: такое сообщение должно пройти ретраи, а не сразу улететь в DLT.
Где спотыкаются
Говорят, что Kafka сама перекладывает сообщение в DLQ. Это делает консьюмер, и если его не настроили, сообщение либо повторяется бесконечно, либо пропускается с одной строкой в логе.
Не знают про ядовитое сообщение (poison pill). Если ошибку не обработать или ретраить без лимита, консьюмер спотыкается на нём снова и снова, партиция встаёт, lag растёт.
Проверяют только лог. Запись об ошибке ещё не значит, что сообщение не потерялось: нужно найти его в DLT и понимать, как его потом переобработать.