События и очереди

2 мин чтения ·

Dead Letter Queue: сообщение не обработано — кто это заметит?

Сообщение ушло в отдельную очередь. Это ещё не решение проблемы клиента — скорее начало расследования.

Заказ попал в очередь, но склад его не обработал: в сообщении оказались данные, которых текущая версия системы не понимает. Автоматическая повторная попытка закончилась тем же. Потом ещё раз. Если продолжать бесконечно, можно загрузить обработчик бесполезной работой и задержать остальные заказы.

Dead Letter Queue, или DLQ, отделяет сообщения, которые обычный поток не сумел обработать. Однако назвать это «обработкой ошибки» было бы слишком оптимистично. Мы всего лишь перестали мешать остальным и сохранили проблему для решения.

Когда повтор помогает, а когда нет

Если внешняя база временно недоступна, попытка позже может завершиться успешно. Для таких ошибок нужны ограниченные повторы с задержкой. Но если поле обязательное, а в сообщении его нет, повтор ничего не исправит. То же касается неизвестной версии контракта или бизнес-состояния, с которым обработчик не умеет работать.

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

Ошибка осталась, бизнес-процесс — тоже

Клиенту не станет легче от сообщения «в DLQ поступило 18 записей». Ему нужен выполненный заказ или понятное объяснение задержки. Поэтому для DLQ нужен владелец: кто увидит рост, кто определит причину и кто решит, следует ли операцию повторять, исправлять вручную или завершать иным способом.

Полезно измерять возраст самой старой необработанной записи и число затронутых бизнес-операций, а не только размер очереди. Некоторые сообщения могут быть важнее других: ошибка фонового отчёта и потерянное подтверждение платежа требуют разной реакции.

Почему опасно просто вернуть все сообщения назад

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

Повторная обработка должна учитывать идемпотентность, состояние бизнес-объекта и версию сообщения. Иногда правильным действием будет не технический replay, а отдельная компенсирующая операция.

Не стоит забывать и о данных внутри DLQ: сообщения могут содержать персональную информацию, поэтому права доступа и срок хранения имеют значение.

Когда отдельная очередь не нужна

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

DLQ полезна, когда позволяет остальной работе двигаться дальше. Но у каждого сообщения в ней должно быть продолжение истории: кто разбирает, что решает и как узнает клиент.