Как настроить throttling submit_sm в SMPP и не потерять сообщения

Как настроить throttling submit_sm в SMPP и не потерять сообщения

Если ваш код шлёт сообщения без ограничения скорости, шлюз рано или поздно начнёт возвращать ошибки ESME_RTHROTTLED — и часть SMS просто не дойдёт. Throttling в SMPP — это контроль частоты отправки PDU submit_sm в секунду. Настроить его можно без сисадмина: нужно знать лимит, который выдал шлюз, и реализовать очередь с задержкой на стороне клиента. Ниже — конкретная механика, типичные ошибки и три шага, с которых начать сегодня.

Что такое throttling submit_sm и почему шлюз режет отправку?

Каждое SMPP-соединение работает в рамках параметра «количество сообщений в секунду» — его называют TPS (transactions per second). Шлюз устанавливает этот лимит при выдаче логина и пароля. Когда клиент превышает TPS, сервер отвечает на submit_sm кодом ошибки ESME_RTHROTTLED (0x00000058). При этом само соединение обычно не рвётся — сессия остаётся, но сообщение не принято к отправке.

Важна разница между двумя ситуациями. Первая: сообщение просто не принято, и клиент должен повторить его чуть позже. Вторая: клиент игнорирует ошибку и продолжает слать — тогда шлюз может принудительно закрыть сессию или поставить аккаунт в throttle-режим на несколько минут. Реальная скорость доставки абоненту при этом зависит ещё и от загруженности операторских маршрутов, поэтому гнать сообщения «на максимум» не имеет смысла: итоговая задержка всё равно определяется не только вашим TPS (quicktel.ru).

Как узнать свой лимит TPS и откуда он берётся?

Лимит TPS — это параметр, который шлюз назначает конкретному аккаунту при подключении. Получить его можно двумя способами. Первый: запросить у поддержки шлюза напрямую — при выдаче логина и пароля провайдер обычно указывает лимиты отправки в таблице параметров подключения (smsp.by). Второй: провести нагрузочный тест вручную — постепенно наращивать частоту submit_sm и зафиксировать момент, когда сервер начинает возвращать ESME_RTHROTTLED.

Нагрузочный тест показывает не только пороговое значение TPS, но и поведение шлюза под нагрузкой: когда растёт очередь, как быстро сервер восстанавливается после перегрузки и сколько ESME_RTHROTTLED приходит подряд до стабилизации (smpp.by). Тест лучше проводить на тестовых номерах, а не на живой базе.

Как реализовать throttling на стороне клиента?

Шлюз не выравнивает поток за вас. Ограничение скорости — задача вашего кода или промежуточной очереди. Есть три рабочих подхода.

Подход Как работает Подходит когда
Sleep между PDU После каждого submit_sm вставляется пауза: 1000 мс / TPS Один поток, небольшой объём
Token bucket / leaky bucket Алгоритм выдаёт «токены» со фиксированной скоростью; отправка идёт только при наличии токена Многопоточная отправка, пики трафика
Очередь с воркером Все сообщения кладутся в очередь (Redis, RabbitMQ и т.п.), воркер вытягивает их с нужным TPS Высокая нагрузка, несколько SMPP-сессий

Алгоритм token bucket — наиболее предсказуемый вариант для отправки SMS. Он сглаживает пики: если за секунду пришло 50 сообщений при лимите 30 TPS, лишние 20 встают в ожидание, а не теряются. Простой sleep между PDU работает только при строго последовательной отправке — в многопоточном коде он не защищает от превышения лимита.

При повторной отправке после ESME_RTHROTTLED нужна экспоненциальная задержка: первый retry через 1 секунду, второй через 2, третий через 4. Фиксированный retry каждые 500 мс создаёт новую волну ошибок точно в момент, когда шлюз ещё не восстановился.

Как отслеживать превышение лимита по логам?

Поток ESME_RTHROTTLED в логах — главный сигнал. Если за одну минуту таких ответов больше 5–10% от общего числа submit_sm, скорость отправки превышает TPS. Смотреть нужно именно на долю ошибок, а не на абсолютный счётчик: при большом объёме даже единичные THROTTLED могут оказаться нормой при кратковременных пиках.

Удобно логировать три события: момент отправки submit_sm, полученный response с кодом и время до следующего retry. По этому журналу можно построить простой график частоты ошибок за любой промежуток. Если шлюз поддерживает мониторинг через DLR, подключите его — так вы увидите не только транспортные ошибки, но и реальную доставку абоненту.

Сессия при правильно настроенном throttling должна оставаться стабильной часами. Периодические разрывы сессии в сочетании с ESME_RTHROTTLED в логах — признак того, что шлюз агрессивно реагирует на превышение, и лимит нужно снижать.

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

  • Не запрашивать TPS у провайдера и угадывать его по ощущениям — реальный лимит может сильно отличаться от «стандартного».
  • Делать retry сразу после ESME_RTHROTTLED без задержки — это создаёт ещё больше ошибок вместо того, чтобы дать шлюзу восстановиться.
  • Считать, что один поток с sleep достаточен при многопоточной отправке — несколько потоков суммируют свои запросы и легко превышают лимит.
  • Игнорировать ESME_RTHROTTLED и не логировать отдельно — тогда потери сообщений обнаруживаются только постфактум по жалобам.
  • Настраивать TPS на уровне лимита без запаса — при любом пике трафика начнутся ошибки; разумно держать реальную скорость на 10–15% ниже заявленного лимита.

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

  1. Запросите у провайдера шлюза точный TPS вашего аккаунта — это один короткий запрос в поддержку, ответ обычно приходит в течение рабочего дня.
  2. Добавьте в лог отдельную строку для ESME_RTHROTTLED с временной меткой — так вы сразу увидите, есть ли превышение прямо сейчас.
  3. Реализуйте задержку между submit_sm по формуле 1000 мс / TPS и проверьте, пропали ли THROTTLED-ошибки в логах в течение следующего часа отправки.
Полезные ссылки как настроить мониторинг доступности SMPP-шлюза через Telegram-бота, как настроить автоматические отчёты по SMS через Webhook.