Приоритеты SMS-трафика: как отделить OTP от массовых рассылок

Приоритеты SMS-трафика нужны, чтобы короткоживущий код входа не ждал за большой маркетинговой кампанией. Если все сообщения идут через одну очередь, один лимит и один маршрут, массовая отправка способна занять доступную пропускную способность. Формально система работает, но срочные уведомления приходят слишком поздно.
Разделение трафика не означает, что рекламные сообщения всегда «плохие», а OTP всегда важнее всего. Приоритет задаётся влиянием задержки на пользователя и бизнес-процесс. Его нужно закрепить в архитектуре, иначе в момент инцидента любая команда объявит свой поток критичным.
Какие классы трафика выделить
Удобно начать с трёх классов:
- аутентификационный — OTP, подтверждение критичного действия, восстановление доступа;
- сервисный — статусы заказа, оплаты, записи, аварийные и договорные уведомления;
- массовый — рекламные и информационные кампании, которые допустимо растянуть во времени.
Внутри сервисного класса могут быть уровни. Сообщение об отмене рейса срочнее ежемесячного напоминания. Но чрезмерно сложная шкала создаёт больше ошибок, чем пользы. Обычно достаточно 3–4 понятных уровней с примерами.
Разница между рекламным и сервисным назначением разобрана в статье про разделение SMS-сценариев. Здесь классификация используется именно для управления техническим потоком.
Отдельные очереди
Самый прозрачный способ — разные очереди SMS-сообщений для критичного, обычного и массового трафика. Воркеры могут быть общими, но планировщик резервирует мощность каждому классу.
Одна приоритетная очередь тоже возможна, однако она сложнее в эксплуатации. При постоянном потоке высокого приоритета низкие задачи могут не исполняться. Нужен механизм справедливости: например, после нескольких критичных сообщений обработать одно обычное либо заранее выделить долю пропускной способности.
Не стоит менять приоритет старой задачи только потому, что она долго ждёт. Просроченная рекламная SMS не становится OTP. Для устаревших событий действует TTL и отмена, а не бесконечное повышение.
Резервирование пропускной способности
Допустим, маршрут способен стабильно отправлять 100 сообщений в секунду. Если массовой кампании разрешить занять все 100, срочный поток попадёт в очередь. Практичнее ограничить кампанию, например, большей частью доступной скорости, оставив резерв критичным событиям.
Конкретные числа определяются замерами и договором с провайдером. Важны правила:
- резерв действует до внешнего SMS API, а не только внутри приложения;
- лимиты разделены по отправителям и маршрутам, если они независимы;
- при росте OTP массовый поток автоматически замедляется;
- неиспользованный резерв можно временно отдавать обычным задачам;
- возврат мощности происходит плавно, без нового пика.
Разные маршруты и аккаунты
Для критичного трафика иногда используют отдельный маршрут, API-учётную запись или подключение. Это уменьшает взаимное влияние лимитов, баланса и настроек Sender ID. При этом резервный путь нужно регулярно проверять: «запасной» маршрут, который не использовали полгода, может не иметь актуального шаблона или имени отправителя.
Разные маршруты не отменяют дедупликацию. При переключении после таймаута нельзя одновременно отправить одну операцию по двум путям. Общий ключ идемпотентности должен сохраняться на уровне вашего сервиса.
Приоритет и стоимость
Более надёжный или быстрый маршрут может стоить дороже. Поэтому правило маршрутизации связывают не только с техническим приоритетом, но и с допустимым бюджетом. Для OTP оправдана высокая цена за низкую задержку, а массовую кампанию можно отправлять в более широком окне.
Решение не должно приниматься по средней стоимости всех SMS. Считайте расходы и показатели отдельно по классу: цена доставленного OTP, цена сервисного уведомления, стоимость конверсии кампании. Общий подход начинается с понимания, из чего складывается цена SMS-рассылки, после чего затраты разносят по владельцам сценариев.
Дедлайны для каждого класса
Критичность проявляется в сроке полезности. OTP действует минуты, статус доставки — часы, а плановая кампания может отправляться до конца выбранного окна. У каждой задачи должен быть expires_at, и воркер обязан проверить его перед отправкой.
Если критичная очередь задерживается, это повод для немедленного алерта. Если массовая очередь растёт, система может просто растянуть кампанию в согласованном окне. Одна метрика длины очереди не передаёт эту разницу.
Мониторинг по классам
Для каждого типа трафика отслеживайте:
- время от события до приёма SMS API;
- время до финального DLR;
- долю сообщений внутри целевого срока;
- возраст самой старой задачи;
- долю просроченных и отменённых;
- нагрузку и ошибки по маршруту;
- использование зарезервированной мощности;
- стоимость и число сегментов.
Среднее по всем сообщениям скрывает проблему. Миллион неспешных уведомлений может сделать красивой общую статистику, пока небольшая доля OTP систематически опаздывает.
Аварийное поведение
Заранее решите, что происходит при деградации. Возможные действия: остановить старт новых кампаний, снизить их скорость, переключить критичный поток на проверенный резервный маршрут, сократить число повторов для устаревающих задач и уведомить дежурную команду.
Ручная кнопка «поставить кампании на паузу» полезна, но не должна быть единственной защитой. Автоматический порог по задержке критичного класса помогает остановить массовый поток до того, как обращения пользователей покажут проблему.
Проверка перед запуском
Создайте тестовый пик массовых задач и одновременно отправляйте контролируемый поток OTP. Убедитесь, что массовая очередь растёт, а задержка критичных сообщений остаётся в целевом диапазоне. Затем отключите основной маршрут и проверьте резерв, дедупликацию и отмену просроченных кодов.
Отдельно проверьте права: маркетолог не должен случайно назначить рекламной кампании системный приоритет без согласования. Класс трафика лучше определять по зарегистрированному сценарию и версии шаблона.
Матрица решений
Чтобы приоритет не зависел от настроения команды, составьте короткую матрицу. Для каждого класса укажите целевой срок, допустимый backlog, максимальное число повторов, маршрут по умолчанию, резерв, бюджетный предел и действие при деградации.
Например, у короткоживущего OTP при нарушении задержки массовая очередь ставится на паузу, а просроченные коды отменяются. У плановой кампании допустимо уменьшить скорость и продолжить в следующем разрешённом окне. У аварийного уведомления может быть отдельный дежурный и подтверждённый резервный путь.
Матрица хранится рядом с конфигурацией и регулярно сверяется с ней. Документ, где написано «OTP — высокий», бесполезен, если production-воркер всё равно читает единую FIFO-очередь.
Защита от неверной классификации
Система проверяет, какие шаблоны разрешены для каждого класса. Массовый пользовательский текст нельзя отправить через OTP-учётную запись только потому, что вызывающий сервис передал priority=critical. Класс выводится из зарегистрированного scenario ID, а исключение требует отдельного права и аудита.
Периодический отчёт ищет нехарактерные объёмы: внезапный миллион «критичных» задач, рост неизвестного класса или постоянное использование резерва. Такие отклонения часто указывают на ошибку интеграции раньше, чем проявится задержка.
Что увидит пользователь
При перегрузке интерфейс не должен обещать «код отправлен», если задача ещё не принята в критичный контур. Лучше сообщить нейтральный результат и дать управляемую возможность повторить позже. Повторный клик сохраняет тот же бизнес-контекст и не обходит серверные лимиты.
Для плановых сообщений задержка обычно невидима, но перенос за согласованное время отправки требует отмены или нового планирования. Приоритет — внутренний механизм; он не должен создавать неожиданные ночные SMS после восстановления очереди.
Итог
Приоритеты SMS-трафика работают, когда закреплены в очередях, лимитах, маршрутах, дедлайнах и метриках. Простая метка high ничего не гарантирует. Резерв мощности для OTP, управляемая скорость массовых кампаний и проверенный аварийный сценарий позволяют доставлять срочные сообщения вовремя даже в самый нагруженный день.