Сбой SMS-провайдера: план действий и резервный маршрут

Сбой SMS-провайдера нельзя исправить только бесконечными повторами. Пока внешний сервис недоступен, ретраи увеличивают нагрузку, очередь стареет, а сообщения теряют актуальность. Нужен заранее подготовленный план: как обнаружить проблему, защитить данные, определить затронутые сценарии, безопасно включить резерв и вернуться на основной маршрут.
План полезен и при частичной деградации. API может отвечать, но DLR задерживаются; один оператор может давать ошибки; массовые сообщения идут нормально, а OTP опаздывают. Поэтому первый шаг — не переключение, а точное определение симптома.
Как понять масштаб
Сопоставьте несколько сигналов:
- доступность и задержку SMS API;
- долю 429, 5xx и таймаутов;
- возраст очереди по классам трафика;
- скорость появления DLR;
- долю доставленных и финальных ошибок;
- распределение по операторам, маршрутам и Sender ID;
- результат контрольных отправок.
Если API не отвечает всем, проблема общая. Если выросла задержка только одного направления, переключать весь трафик может быть вредно. Если перестали приходить callbacks, сами SMS могут продолжать доставляться — тогда нужен отдельный разбор webhook статусов.
Первые действия
Зафиксируйте время начала и назначьте координатора инцидента. Остановите старт новых массовых кампаний и снизьте поток, который не имеет срочного дедлайна. Не удаляйте очередь и не запускайте ручные повторы без общего решения.
Дальше разделите задачи:
- Критичные и ещё актуальные сообщения.
- Сервисные сообщения, которые могут подождать.
- Массовые кампании, которые можно поставить на паузу.
- Уже просроченные задачи, которые нельзя отправлять после восстановления.
Так команда защищает важные сценарии и не превращает ремонт в волну вчерашних уведомлений.
Поведение очереди
Очередь SMS-сообщений должна продолжать устойчиво принимать события либо честно отказать вызывающей системе по согласованному сценарию. Важно следить за диском, лимитами хранения и скоростью роста. Если входящий поток выше будущей способности обработки, оцените время восстановления заранее.
Все задачи сохраняют idempotency key, число попыток и send_before. Временные ошибки переносятся по backoff, но после достижения срока жизни SMS задача становится просроченной и больше не вызывается.
Когда включать резерв
Резервный маршрут включают по заранее определённому условию: подтверждённая недоступность, нарушение SLO критичного класса или конкретная проблема направления. Он должен быть технически и организационно готов до инцидента:
- зарегистрированы Sender ID и шаблоны;
- проверены API-ключи, баланс и лимиты;
- настроен callback и нормализация статусов;
- известна стоимость;
- тестовая отправка выполняется регулярно;
- правила обработки данных согласованы.
Новый маршрут посреди аварии — это не резерв, а отдельная миграция с неизвестными рисками.
Как избежать двойной отправки
Самая опасная зона — запросы с неопределённым результатом. Основной провайдер мог принять SMS, хотя клиент получил таймаут. Если сразу отправить её через резерв, адресат получит дубль.
Для каждого такого запроса попытайтесь выяснить состояние по message ID или client request ID. Используйте общий ключ идемпотентности и централизованный реестр операций. Если провайдеры не поддерживают сквозную дедупликацию, зафиксируйте консервативное правило для конкретного сценария: что хуже — возможный дубль или возможная недоставка.
Для OTP иногда безопаснее разрешить пользователю запросить новый код, инвалидировав старый, чем автоматически отправлять оба маршрута. Для юридически значимого уведомления решение может быть другим.
Коммуникация внутри компании
Поддержка должна получить понятный статус: какие сценарии затронуты, с какого времени, что видит пользователь и какой ответ давать. Бизнес-команды узнают, можно ли запускать кампании. Разработчики и провайдер обмениваются message ID, временными интервалами и кодами, а не скриншотами без контекста.
Ведите журнал решений: когда остановили поток, почему включили резерв, какие лимиты изменили. Это ускоряет разбор и защищает от одновременных противоречивых действий нескольких команд.
Восстановление
После возвращения API не открывайте весь поток мгновенно. Сначала проверьте контрольные сообщения и DLR, затем постепенно увеличивайте скорость. Перед обработкой накопленной очереди отфильтруйте просроченные задачи и сохраните порядок приоритетов.
Следите, чтобы текущие критичные события не оказались за старым backlog. Часть мощности резервируют новому потоку, а накопление разбирают отдельно. Если основной и резервный маршруты работали параллельно, сверяют идентификаторы и ищут возможные дубли.
Возвращаться с резерва тоже нужно плавно. Резкое переключение может создать пик и скрыть повторную деградацию.
Разбор после инцидента
Разбор отвечает не «кто виноват», а почему защита не остановила влияние. Зафиксируйте временную шкалу, затронутые сценарии, число просроченных и дублированных сообщений, расходы резерва и время до обнаружения.
Проверьте:
- сработали ли алерты до обращений клиентов;
- было ли понятно, кто принимает решение;
- хватило ли наблюдаемости в логах SMS;
- резерв действительно работал;
- TTL остановил устаревшие задачи;
- массовый поток уступил критичному;
- инструкция соответствовала реальности.
Каждый вывод превращают в конкретное изменение: новый мониторинг, автоматическую паузу кампаний, регулярный тест резерва или уточнение runbook.
Минимальный тренировочный сценарий
Не ждите реальной аварии. В тестовой среде или согласованном окне заблокируйте основной endpoint, накопите задачи и проверьте circuit breaker. Затем включите резерв для ограниченного набора тестовых номеров, восстановите основной маршрут и разберите backlog с учётом TTL.
Тренировка должна подтвердить не только факт отправки, но и отсутствие дублей, корректные статусы, права доступа и работу коммуникации между командами.
Таблица решений до аварии
Для каждого симптома заранее запишите действие и ответственного. Например: массовые 5xx — остановить новые кампании и открыть circuit breaker; рост задержки одного оператора — ограничить только затронутый маршрут; отсутствие DLR при нормальном API — не переотправлять сообщения, а переключить обработчик статусов в режим расследования.
У решения есть порог, срок повторной оценки и условие отмены. Это защищает от двух крайностей: слишком раннего переключения всего трафика и бесконечного ожидания, пока проблема уже влияет на клиентов.
Отдельно зафиксируйте, какие действия запрещены: удаление backlog, повтор всех таймаутов новым ключом, включение непроверенного маршрута, публикация персональных данных в общем чате.
Неопределённые операции
Создайте отдельное состояние для запросов, у которых неизвестен факт приёма. Такие задачи нельзя смешивать с точными отказами. Команда пытается найти их по client ID, запрашивает провайдера и принимает решение по риску сценария.
После инцидента количество неопределённых операций должно сойтись с результатом: найденные message ID, сознательно повторённые, отменённые и оставшиеся на ручной разбор. Эта сверка важнее общей цифры backlog — именно в неопределённой группе чаще появляются дубли.
Внешнее сообщение клиентам
Не каждый технический сбой требует массового уведомления. Если влияние заметно, поддержка и статус-страница сообщают фактический симптом и обходной путь без неподтверждённых причин. Для OTP интерфейс может предложить повтор позже или другой заранее предусмотренный способ входа.
После восстановления не обещайте доставку старых SMS: часть задач законно отменена по TTL. Сообщение пользователю должно соответствовать реальному поведению системы.
Итог
План сбоя SMS-провайдера объединяет мониторинг, очереди, TTL, приоритеты, дедупликацию и проверенный резерв. Его цель — не отправить всё любой ценой, а сохранить актуальные критичные уведомления, не допустить лавину повторов и безопасно восстановить нормальный поток. Подготовленный маршрут и проведённая тренировка ценнее любой инструкции, написанной уже во время аварии.