Как SMPP-шлюз помогает сократить число неотвеченных OTP-кодов

Как SMPP-шлюз помогает сократить число неотвеченных OTP-кодов

OTP-код живёт секунды. Если он пришёл с задержкой в 30–40 секунд или не пришёл вовсе — пользователь либо запросит повторный код, либо уйдёт. SMPP-шлюз решает эту проблему на уровне протокола: постоянное TCP-соединение вместо HTTP-запроса на каждое сообщение убирает задержки на установку сессии и даёт прямой контроль над статусами доставки. В статье разберём, где именно теряются OTP-коды и что конкретно настроить, чтобы этого не происходило.

Почему OTP-коды теряются ещё до пользователя?

Большинство потерь происходит не у оператора, а раньше — между вашим сервером и SMS-шлюзом. HTTP API при каждой отправке заново устанавливает соединение: DNS-резолвинг, TCP-handshake, TLS-согласование. На это уходит от 200 мс до нескольких секунд, и при всплеске нагрузки запросы начинают вставать в очередь или падать по таймауту.

SMPP работает иначе. Соединение устанавливается один раз при старте и держится постоянно. Сообщение уходит в шлюз через уже открытый канал — задержка на отправку падает до единиц миллисекунд. Для OTP это принципиально: разница между «код пришёл сразу» и «код пришёл через минуту» — это разница между завершённой транзакцией и потерянным клиентом.

Вторая точка потерь — отсутствие квитанций о доставке. Без delivery receipt сервер не знает, дошёл ли код. Повторный запрос пользователя уходит в пустоту, потому что система считает первый код доставленным. SMPP передаёт deliver_sm с реальным статусом доставки от оператора, и при правильно настроенном fallback-маршруте сервер может автоматически повторить отправку через другой маршрут, если первый вернул ошибку.

Что конкретно настроить в SMPP для OTP-трафика?

Первое — тип привязки. Для OTP нужен transceiver (bind_transceiver): он одновременно отправляет сообщения и принимает квитанции о доставке. Если использовать только transmitter, статусы не придут и вы будете работать вслепую.

Второе — размер окна (window size). Это количество сообщений, которые можно отправить без ожидания ответа на предыдущие. Для OTP-трафика с короткими сообщениями оптимальное значение подбирается под реальный профиль нагрузки: слишком маленькое окно создаёт искусственную очередь, слишком большое — перегружает шлюз и оператора (источник: quicktel.ru). Перед тем как фиксировать значение, стоит провести нагрузочное тестирование на реальных объёмах.

Третье — enquire_link. Это keepalive-пакет, который проверяет, живо ли соединение. Без него «упавший» канал обнаруживается только в момент следующей отправки — то есть OTP-код просто не уходит. Интервал enquire_link обычно ставят от 30 до 60 секунд.

Четвёртое — кодировка. Кириллица в OTP-коде встречается редко, но если шаблон содержит хотя бы один символ вне GSM-7 таблицы, сообщение уйдёт в UCS-2 и максимальная длина сократится со 160 до 70 символов. OTP-шаблон вида «Ваш код: 4821» лучше держать в латинице и цифрах — это гарантирует GSM-7 и одиночный сегмент. Подробнее о выборе кодировки — в материале про UCS-2 и GSM-7 в SMPP.

Параметр HTTP API SMPP
Установка соединения На каждый запрос Один раз при старте
Задержка отправки 200 мс — несколько секунд Единицы миллисекунд
Квитанции о доставке Через вебхук, возможны потери deliver_sm в том же соединении
Пиковая нагрузка Очередь и таймауты Контролируется через window size
Обнаружение обрыва По ошибке следующего запроса enquire_link каждые 30–60 сек

Как проверить, что шлюз справляется с нагрузкой?

Нагрузочное тестирование SMPP показывает, сколько сообщений в секунду выдерживает конкретное соединение, когда растёт очередь и как шлюз реагирует на ошибки (источник: smpp.by). Без такого теста нельзя утверждать, что SMPP-канал лучше API: преимущество подтверждается измерением, а не ожиданием (источник: quicktel.ru).

Для теста достаточно инструмента, который умеет открывать SMPP-сессию и слать submit_sm с заданным TPS. Фиксируйте три показателя: время от submit_sm до submit_sm_resp, время до получения deliver_sm и процент сообщений без квитанции за контрольный период. Если deliver_sm не приходит на 5% и более сообщений — проблема либо в window size, либо в маршруте до оператора.

Отдельно проверьте поведение при обрыве TCP. Шлюз должен переподключиться автоматически и без потери сообщений из очереди. Если этого не происходит — смотрите на настройки reconnect-логики на стороне вашего SMPP-клиента.

Типичные ошибки при настройке OTP через SMPP

  • Используют bind_transmitter вместо transceiver — квитанции о доставке не приходят, повторные отправки не работают.
  • Ставят enquire_link с интервалом больше 5 минут или отключают совсем — «упавшее» соединение обнаруживается только при следующей отправке.
  • Не тестируют кодировку шаблона — один кириллический символ в тексте переключает всё сообщение в UCS-2 и сокращает лимит до 70 символов.
  • Игнорируют TPS-лимиты оператора — шлюз принимает сообщения быстрее, чем оператор их обрабатывает, и часть OTP-кодов встаёт в очередь на минуты.
  • Не настраивают fallback-маршрут — при сбое одного оператора коды просто не доходят вместо автоматического переключения.

Когда SMPP оправдан, а когда достаточно HTTP API?

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

SMPP оправдан, когда задержка доставки больше 3–5 секунд уже ощущается пользователем как сбой. Интернет-магазин с пиком заказов в выходные, логистический сервис с подтверждением слотов доставки, медицинская запись с напоминаниями о визите — во всех этих случаях потерянный OTP стоит реального клиента. Настроить приоритет SMS-трафика через SMPP можно отдельно для OTP-очереди, чтобы она не конкурировала с маркетинговыми рассылками за пропускную способность канала.

3 шага, которые можно сделать на этой неделе:

  1. Проверьте тип привязки в своём SMPP-клиенте — должен быть transceiver, иначе квитанции о доставке не приходят.
  2. Запустите нагрузочный тест на реальном объёме OTP-трафика и зафиксируйте процент сообщений без deliver_sm за 10 минут.
  3. Проверьте все OTP-шаблоны на наличие кириллицы — если она есть, переведите текст в латиницу и цифры, чтобы гарантировать GSM-7 и одиночный сегмент.