Dead Letter Queue для SMS: как разбирать сообщения после неудачных попыток

Не каждую SMS-задачу удаётся обработать автоматически. Временный сетевой сбой можно повторить, но неверная схема события, отсутствующий шаблон или неизвестный код провайдера не исправятся от десятой попытки. Если такие задачи бесконечно возвращать в основную очередь, они расходуют ресурсы и скрывают системную проблему.
Dead Letter Queue, или DLQ, — отдельное хранилище для задач, которые не удалось обработать по заданной политике. Она не является мусорной корзиной. У каждой записи остаются причина, история попыток и понятный путь: исправить и переиграть, закрыть как неактуальную или эскалировать владельцу.
Когда переводить задачу в DLQ
Критерии задаются заранее:
- исчерпан лимит временных повторов;
- событие не соответствует поддерживаемой версии схемы;
- обязательные данные отсутствуют или невалидны;
- шаблон или Sender ID не найден;
- получен постоянный код ошибки провайдера;
- задача просрочена по TTL;
- обработчик обнаружил состояние, которое требует решения человека.
Не все случаи означают повторную отправку. Просроченный OTP следует закрыть, а ошибку новой версии события — исправить и переобработать без потери бизнес-смысла.
Отличие DLQ от обычной очереди
Основная SMS-очередь оптимизирована для автоматического потока. DLQ оптимизирована для расследования. В ней важнее контекст ошибки, фильтры, владелец и контролируемый replay.
Запись должна содержать event ID, correlation ID, тип события, версию, время первой и последней попытки, число попыток, классификацию ошибки и безопасную ссылку на исходные данные. Полный текст, номер телефона и секреты не следует копировать без необходимости.
Классификация ошибок
Единая строка failed мало помогает. Разделите причины хотя бы на категории:
- transient — временная внешняя проблема;
- validation — некорректные входные данные;
- configuration — отсутствует шаблон, маршрут или настройка;
- contract — неизвестный ответ или несовместимая схема;
- security — ошибка подписи, доступа или политики;
- expired — сообщение потеряло смысл;
- manual — требуется бизнес-решение.
Категория определяет владельца и допустимость replay. Она также показывает тенденции: рост contract после релиза отличается от единичных невалидных номеров.
Повторный запуск
Кнопка «переотправить всё» опасна. Перед replay нужно устранить причину, выбрать ограниченную группу, проверить TTL и убедиться, что задача ещё актуальна. Новая попытка сохраняет исходный event ID и idempotency key, если речь о той же логической отправке.
Replay лучше выполнять в новую очередь с отметкой источника и пользователем, который его инициировал. Тогда основная обработка остаётся наблюдаемой, а аудит показывает, почему старое событие вернулось в поток.
Если сообщение могло быть принято провайдером до сбоя, сначала выясните его статус по client message ID. Слепой повтор неоднозначного запроса создаёт дубли.
Массовая проблема
Тысячи одинаковых записей в DLQ обычно означают одну причину, а не тысячи отдельных инцидентов. Группируйте по коду ошибки, версии обработчика, шаблону, сценарию и времени начала. Интерфейс должен позволять увидеть representative sample без просмотра каждой строки.
При резком росте включается автоматический предохранитель: пауза проблемного сценария, отключение релиза или переключение маршрута. DLQ фиксирует последствия, но не должна быть единственным алертом.
Срок хранения и доступ
Храните запись достаточно долго для расследования и безопасного replay, но не бесконечно. Политика зависит от бизнес-сценария и требований к персональным данным. После завершения можно оставить агрегированную причину и технические ID, удалив payload.
Доступ к DLQ часто позволяет повторно запустить сообщения, поэтому это привилегированная операция. Нужны персональные учётные записи, журнал действий и разделение прав на просмотр и replay.
Метрики
Следите за:
- числом новых DLQ-записей по категориям;
- долей относительно общего потока;
- возрастом самой старой открытой записи;
- временем до назначения владельца и решения;
- количеством replay и их результатом;
- сценариями, шаблонами и версиями с наибольшим вкладом;
- повторным попаданием одной задачи в DLQ.
Нулевой размер DLQ не всегда хорош: если система удаляет неудачные задачи или бесконечно повторяет их в основной очереди, проблемы просто не видны.
Runbook разбора
Для дежурной команды полезна короткая инструкция:
- Подтвердить масштаб и начало проблемы.
- Сгруппировать записи по причине.
- Проверить последние релизы и конфигурацию.
- Остановить источник новых ошибок, если поток растёт.
- Определить, какие сообщения ещё актуальны.
- Исправить причину и протестировать одну запись.
- Переиграть ограниченный пакет с мониторингом.
- Зафиксировать решение и добавить автоматическую защиту.
Типичные ошибки
- использовать DLQ как постоянный архив;
- хранить там секреты и полный персональный payload;
- не назначать владельца;
- повторять просроченные сообщения;
- генерировать новый ID при каждом replay;
- смешивать ошибки отправки и финальную недоставку оператором;
- не ограничивать массовый повтор;
- удалять запись сразу после первого успешного replay без аудита.
Итог
Dead Letter Queue делает необрабатываемые SMS-задачи видимыми и управляемыми. Хорошая DLQ хранит минимум безопасного контекста, классифицирует причины и поддерживает контролируемый replay. Её ценность не в количестве накопленных ошибок, а в коротком пути от сигнала до исправления и предотвращения повторения.