остоянная закономерность: предприятие запрашивает 100 SMS в секунду, направляет свое приложение на точку привязки и измеряет двенадцать. Пропускная способность в порядке. SMSC в порядке. Никого не ограничили. Трафик просто ползет, и первое, что приходит в голову, — это всегда винить маршрут. Но почти никогда дело не в маршруте. Дело в окне.
SMPP — это асинхронный протокол, который в большинстве интеграций по ошибке выполняется синхронно. Понимание причин этого — разница между оплатой за пропускную способность и её получением.
Что на самом деле представляет собой это окно
«Окно» — это количество PDU, которые вы могли отправить, но еще не получили подтверждения, в рамках одной операции привязки в любой момент времени. Отправьте submit_sm, и SMSC ответит submit_sm_resp — но SMPP никогда не требовал от вас ожидания этого ответа перед отправкой следующего сообщения. «Окно» — это то, насколько далеко вперед вам разрешено двигаться.
При окне в 1 сообщение отправляется, вы ждете, получаете, отправляете снова. Ваша пропускная способность теперь ограничена временем кругового пути, а не чем-либо, о чем вы договорились в коммерческом плане. При времени кругового пути в 40 мс это 25 сообщений в секунду — независимо от того, что указано в вашем контракте. При окне в 10 сообщений у вас одновременно обрабатывается десять сообщений, и по одному и тому же каналу передается примерно в десять раз больше трафика по одному и тому же соединению.
Размер окна — это самый важный фактор, определяющий пропускную способность, которую вы получаете от привязки, и именно этот параметр чаще всего оставляют по умолчанию в библиотеке, что незаметно ограничивает интеграцию значительно ниже согласованной скорости.
Почему так много библиотек по умолчанию используют один из вариантов?
Значение окна, равное 1, является безопасным значением по умолчанию для автора библиотеки. Оно не требует состояния корреляции, учета тайм-аутов и переупорядочивания: каждый запрос имеет ровно один ожидающий ответ, поэтому неопытный клиент может рассматривать SMPP как запрос/ответ и никогда не заметить разницы. Это работает, это легко понять, и это медленно. Многие клиентские библиотеки SMPP поставляются именно с таким значением, и оно никогда не пересматривается, потому что ничего не кажется сломанным — сообщения приходят, просто не быстро.
Порядковые номера — это то, что делает возможным создание окна.
Каждый блок данных SMPP содержит в своем 16-октетном заголовке номер sequence_number. Когда одновременно обрабатывается несколько запросов, этот номер является единственным, что связывает каждый запрос submit_sm_resp с запросом submit_sm, который его вызвал. Не гарантируется, что ответы придут в порядке отправки запросов, поэтому клиент, работающий с окном размером больше 1, должен хранить карту незавершенных порядковых номеров и сопоставлять их по мере поступления.
Два правила имеют значение. Никогда не используйте повторно порядковый номер, пока он еще находится в процессе передачи — задержка ответа на повторно использованный номер будет приписана неправильному сообщению. И всегда устанавливайте тайм-аут для записей: если ответ так и не приходит, слот должен быть освобожден, иначе эффективное окно сократится до нуля за время сеанса, что приводит к раздражающему эффекту быстрого начала соединения и его ослабления в течение нескольких часов.
Вы можете наблюдать за этим пошагово в нашем симулятор сеанса SMPP — там отображается sequence_number в заголовке каждого PDU, а также то, какой ответ соответствует какому запросу.
Размер окна и количество кадров в секунду (TPS) — это разные пределы.
Эти понятия постоянно путают. TPS — это ограничение скорости, устанавливаемое оператором: количество отправленных данных в секунду, измеренное за определенный промежуток времени. Окно SMPP — это ограничение параллельного доступа, которое вы настраиваете: количество PDU, находящихся в обработке в данный момент времени. Они взаимодействуют, но это не одно и то же число.
Зависимость примерно следующая: достижимое количество транзакций в секунду (TPS) ≈ окно ÷ время кругового пути. Окно размером 10 с временем кругового пути 50 мс дает около 200 TPS. Если оператор ограничивает вас 100 TPS, вы достигнете лимита и получите ESME_RTHROTTLED на избыточном трафике. Если оператор разрешает 500 TPS, а ваше окно равно 10, вы никогда не увидите 500 TPS, независимо от объема трафика, который вы предоставляете — вы ограничены параллелизмом, а не скоростью передачи данных.
| Окно | Поездка туда и обратно | Потолок | Симптом |
|---|---|---|---|
| 1 | 40 мс | ~25 Т/с | Договорная ставка так и не была достигнута; связь, похоже, неактивна. |
| 10 | 40 мс | ~250 тонн в секунду | Подходит для большинства корпоративных отправителей |
| 50 | 40 мс | ~1250 тонн в секунду | Только если оператор дал на это согласие; в противном случае ожидайте снижения скорости. |
| 10 | 250 мс | ~40 тонн в секунду | Ограничение по времени задержки — поднимите окно или подойдите ближе. |
Правильное прочтение ESME_RTHROTTLED
ESME_RTHROTTLED (0x00000058) означает, что вы превысили согласованную скорость отправки. Это не отклонение сообщения и не ошибка маршрутизации. Правильный ответ — отступить и повторить попытку отправки сообщения; обработка сообщения как постоянного приводит к незаметному отбрасыванию трафика, который оператор принял бы чуть позже.
Это также сигнал о том, что ваше окно теперь слишком велико для поддерживаемой вами скорости. Если увеличение окна привело к ограничению пропускной способности, а не к её снижению, то ограничение переместилось с параллельного выполнения на контрактное, и следующий разговор будет касаться коммерческих, а не технических аспектов.
enquire_link: другая причина связывания умирает
Соединение, которое ничего не отправляет, выглядит идентично соединению, TCP-соединение которого молча разорвалось — тайм-ауты NAT и брандмауэры с отслеживанием состояния разрывают неактивные сессии, не сообщая об этом ни одной из сторон. Сообщения enquire_link каждые 30–60 секунд подтверждают, что сокет по-прежнему пригоден для использования в обоих направлениях. Если вы пропустите ожидаемое оператором окно, сообщение SMSC приведет к разрыву соединения, обычно в самый неподходящий момент.
Отправьте enquire_link по тому же адресу, по которому вы отправляете запрос, оперативно ответьте на собственный enquire_link объекта SMSC и рассматривайте пропущенный ответ как незавершенную сессию: unbind, переподключитесь, возобновите соединение. Клиент, который продолжает отправлять запросы в полуоткрытый сокет, создает классическую ситуацию, когда все выглядит исправным, но ничего не доставляется.
Как правильно подобрать размер окна на практике
- Измерьте время передачи данных в обе стороны на том устройстве, которое вы фактически используете, а не на своем ноутбуке. Отправьте одно сообщение с окном размером 1 и временем от submit_sm до submit_sm_resp.
- Разделите оговоренное количество сообщений в секунду (TPS) на количество сообщений в секунду, разрешенное для одного цикла передачи. Полученное частное — это ваш минимально допустимый временной интервал.
- Добавьте запас по времени — округлите в большую сторону, затем добавьте примерно 50% — потому что время кругового пути не является постоянным, и окно, размер которого точно соответствует среднему значению, будет работать хуже на медианном уровне.
- Повышайте уровень постепенно, а не одним резким скачком, и следите за появлением ESME_RTHROTTLED. Первое устойчивое снижение мощности покажет, где на самом деле находится предел возможностей оператора.
- Уточните значение у оператора. Некоторые SMSC устанавливают максимальное окно для привязки и будут молча ставить в очередь или отбрасывать запросы, превышающие это ограничение.
- Только после этого следует рассмотреть возможность второй привязки. Множественные привязки увеличивают параллелизм, но также увеличивают количество способов, которыми сессия может завершиться неудачей.
Когда большее количество привязок превосходит большее окно возможностей
Существует предел тому, что может передавать одно TCP-соединение. При наличии нескольких сотен незавершенных PDU (блоков данных) сбои становятся неприятными: проблема с одним сокетом приводит к потере всего трафика, становится заметной блокировка в начале очереди, а восстановление после разрыва означает повторное воспроизведение большого набора передаваемых данных. Большинство операторов предпочтут несколько умеренных сбоев одному огромному, и большинство из них, если их спросят, скажут, какой формат они предпочитают.
Разделение по классам трафика, а не произвольное. Хранение критически важных по времени одноразовых паролей отдельно от массовой рассылки маркетинговых сообщений означает, что маркетинговая кампания не сможет задержать отправку кода авторизации — это решение, касающееся пропускной способности, которое на самом деле является решением, касающимся продукта.
Контрольный список, прежде чем обвинять маршрут.
- Что представляет собой настроенное окно, и кто-нибудь настроил его намеренно?
- Истечет ли срок действия незаполненных порядковых номеров, после чего они будут освобождены?
- Выполняется ли операция enquire_link с интервалом, ожидаемым оператором?
- Повторная отправка ответов ESME_RTHROTTLED осуществляется с задержкой, или же они считаются неудачными?
- Соответствует ли измеренное время в обоих направлениях вашим предположениям при определении размера окна?
- Подтверждаются ли отчёты о доставке (deliver_sm) оперативно — поток неподтвержденных отчётов также может привести к зависанию сессии?
Часто задаваемые вопросы
Какой размер окна SMPP считается оптимальным?
Универсального значения не существует, поскольку правильное значение зависит от времени кругового пути и оговоренной ставки. Практической отправной точкой для корпоративного трафика является значение 10, затем его следует увеличивать до тех пор, пока вы либо не достигнете оговоренного количества транзакций в секунду (TPS), либо не начнете видеть ESME_RTHROTTLED. Размер значения, равный оговоренному TPS × времени кругового пути, плюс примерно 50% запаса, позволяет добиться большинства интеграций с первого раза.
Увеличит ли больший размер окна мою пропускную способность без ограничений?
Нет. Как только размер окна станет достаточно большим, чтобы достичь лимита скорости, установленного оператором, дальнейшее увеличение приведет к появлению сообщений ESME_RTHROTTLED, а не к увеличению количества сообщений. Окно устраняет узкое место в параллельном выполнении; оно не может повысить коммерческий лимит.
Почему пропускная способность снижается в течение нескольких часов, а не сразу?
Это классический симптом наличия незавершенных запросов с порядковыми номерами, которые никогда не истекают по таймауту. Каждый потерянный ответ навсегда занимает слот окна, поэтому эффективное окно уменьшается в течение сеанса, пока привязка не начнет вести себя так, как если бы окно было равно 1. Освобождение слотов по истечении таймаута решает эту проблему.
Является ли ESME_RTHROTTLED окончательной неисправностью?
Нет, и если рассматривать это как потерю трафика, это означает, что вы превысили согласованную скорость в данный момент. Отступите, повторите попытку отправки того же сообщения, и если ограничение скорости сохраняется, уменьшите временной интервал или пересмотрите скорость.
Как часто мне следует отправлять enquire_link?
Обычно интервал составляет от 30 до 60 секунд, и точное значение должно соответствовать ожиданиям оператора. Цель состоит в том, чтобы подтвердить, что потенциально неактивная TCP-сессия всё ещё активна в обоих направлениях, прежде чем NAT или брандмауэр незаметно её отбросят.
Мне использовать одну большую перевязку или несколько меньших?
Как правило, несколько умеренных переключений лучше, чем одно очень большое, поскольку сбой сокета в этом случае обходится вам лишь в часть, а не во всю пропускную способность. Разделение трафика по классам — критически важные по времени пароли отдельно от массовых запросов — позволяет избежать задержки кода авторизации из-за маркетинговой кампании.
Влияет ли этот временной промежуток также на получение отчётов о доставке?
Да, и в обратном направлении. SMSC отправляет вам подтверждения deliver_sm, и если ваше приложение медленно возвращает deliver_sm_resp, поток подтверждений затягивается. При привязке трансивера эта перегрузка может повлиять на всю сессию, поэтому подтверждайте подтверждения оперативно, даже если вы обрабатываете их асинхронно.
Где я могу наблюдать такое поведение, не подключаясь к реальному SMSC?
Наш симулятор сеанса SMPP обрабатывает полную сессию SMPP 3.4 в браузере — привязка, отправка, асинхронное подтверждение доставки, enquire_link и unbind — и отображает поля каждого PDU, сопоставленные с фактическими октетами в сети. Ничего не устанавливается и ничего не отправляется.
Краткая версия
Если соединение работает неэффективно, проверьте окно перед проверкой сети. SMPP по своей природе асинхронен, и большинство интеграций по ошибке запускают его синхронно. Задайте размер окна, исходя из измеренного времени кругового пути и согласованной скорости, засеките время выполнения порядковых номеров, обеспечьте корректную работу enquire_link и повторите попытку ESME_RTHROTTLED с задержкой. Эта последовательность решает подавляющее большинство проблем с пропускной способностью без вмешательства в маршрут.
