Ошибки Throttling и Message Queue Full означают, что SMPP-соединение временно не успевает принять новый объём сообщений. В такой момент нельзя просто удалить SMS или бесконечно повторять отправку без паузы. В статье разберём, как распознать коды ESME_RTHROTTLED и ESME_RMSGQFUL, вернуть сообщение в очередь, выбрать таймаут и ограничить число попыток, чтобы система не создавала дополнительную нагрузку.
Почему SMPP возвращает Throttling Error и Message Queue Full?
SMPP-шлюз обменивается с вашим приложением командами и ответами. При отправке большого потока сообщений провайдер или само соединение может временно ограничить скорость обработки. В ответ приложение получает ошибку throttling, которую часто связывают с кодом ESME_RTHROTTLED.
Причина ESME_RTHROTTLED обычно связана с превышением допустимой скорости запросов. Например, приложение отправляет новые submit_sm, пока сервер ещё обрабатывает предыдущие команды. Сервер отклоняет текущую операцию, потому что канал нужно разгрузить.
Ошибка ESME_RMSGQFUL, или Message Queue Full, указывает на заполнение очереди сообщений. Сервер временно не может принять ещё одну запись. В этом случае повторная попытка сразу после отказа часто приводит к следующему отказу и увеличивает очередь невыполненных задач на стороне приложения.
Для бизнеса в Беларуси такой сценарий встречается при пакетной отправке кодов подтверждения, уведомлений о заказе или сообщений о статусе заявки. Проблема касается технической доставки: текст SMS уже сформирован, но SMPP-соединение не смогло принять его в текущий момент.
Как обработать ESME_RTHROTTLED с правильной паузой?
При получении ошибки ESME_RTHROTTLED сообщение нужно вернуть в очередь. Перед следующей попыткой выдерживают таймаут на этом соединении, равный одной секунде. Это конкретное правило указано в документации Devino по протоколу SMPP.
Пауза относится к соединению, которое вернуло ошибку. Если приложение держит несколько SMPP-сессий, не стоит блокировать все каналы из-за одного отказа. Для каждой сессии нужен собственный счётчик состояния и собственный момент следующей попытки.
Пример последовательности:
- Приложение отправляет SMS через выбранное SMPP-соединение.
- Сервер возвращает
ESME_RTHROTTLED. - Приложение сохраняет сообщение в очереди с исходным идентификатором задачи.
- На этом соединении запускается таймер на 1 секунду.
- После таймера приложение повторяет отправку.
Сообщение лучше возвращать в конец очереди, а не ставить перед всеми остальными задачами. Тогда одна проблемная запись не блокирует остальные SMS и система сохраняет порядок обработки общего потока.
Что делать при Message Queue Full?
При ошибке ESME_RMSGQFUL SMS также возвращают в конец очереди. Документация Devino рекомендует сделать ещё от 3 до 5 попыток доставки, каждый раз повторяя постановку сообщения в конец очереди при той же ошибке.
Важна именно ограниченная серия повторов. Если сообщение возвращается бесконечно, очередь растёт, рабочие процессы заняты повторной обработкой, а новые SMS получают меньше ресурсов. После исчерпания лимита приложение должно перевести запись в отдельный список ошибок и сохранить причину отказа.
| Ошибка | Что означает | Действие приложения | Пауза и лимит |
|---|---|---|---|
ESME_RTHROTTLED |
Скорость отправки ограничена | Вернуть SMS в очередь и повторить через таймаут | 1 секунда на этом соединении |
ESME_RMSGQFUL |
Очередь сообщений на стороне шлюза заполнена | Поставить SMS в конец очереди | От 3 до 5 повторных попыток |
Для Message Queue Full в передаче данных полезно хранить номер попытки, время последней ошибки и текст ответа сервера. Эти поля позволяют отличить временную перегрузку от постоянной технической проблемы, например ошибки авторизации или отключённой сессии.
Как построить очередь и ретраи в SMPP-приложении?
Очередь должна отделять подготовку SMS от её отправки. Бизнес-система создаёт задачу с текстом, номером получателя и внутренним идентификатором. Отдельный отправитель забирает задачу, передаёт её через SMPP и ждёт результата. Если сервер вернул временную ошибку, задача меняет статус на «ожидает повтора».
Для каждой задачи удобно хранить следующие значения:
- уникальный идентификатор сообщения;
- номер попытки отправки;
- код последней SMPP-ошибки;
- время, после которого разрешён новый запуск;
- идентификатор SMPP-соединения;
- финальный статус доставки или причина остановки.
Не удаляйте SMS из основной очереди до получения результата отправки. При временной ошибке запись должна остаться доступной для повторной обработки. При успешном ответе её можно перевести в статус принятой сервером, а при достижении лимита повторов, в журнал неуспешных задач.
Полезно разделить очереди по приоритету. Коды подтверждения и уведомления о состоянии заказа обычно требуют более быстрой обработки, а массовые информационные сообщения могут подождать. Такое разделение снижает риск, что большой пакет второстепенных SMS задержит транзакционные сообщения.
Как избежать повторной отправки одного и того же SMS?
Ретрай запускается только после временной ошибки. Если сервер уже принял команду, а приложение не получило ответ из-за разрыва соединения, повторная отправка может создать дубль. Поэтому система должна различать отрицательный SMPP-ответ и отсутствие ответа.
Для контроля дублей сохраните внутренний ключ сообщения и результат каждой попытки. При восстановлении соединения сначала проверьте состояние сессии и доступные статусы, а потом продолжайте отправку. Нельзя считать отсутствие ответа подтверждением отказа.
Если поток SMS постоянно упирается в ограничения, проверьте настройки скорости и количество параллельных запросов. Для резервного сценария пригодится отдельная инструкция о том, как настроить резервный SMPP-канал и не терять SMS при сбое провайдера.
Какие ошибки чаще всего ломают повторную отправку?
- Повтор без паузы. Приложение получает throttling и тут же отправляет ту же команду снова. Сервер отвечает повторной ошибкой, а очередь растёт.
- Бесконечный ретрай. У задачи нет максимального числа попыток, поэтому одна проблемная запись постоянно занимает обработчик.
- Возврат в начало очереди. Одно SMS блокирует все следующие сообщения. При перегрузке это быстро увеличивает задержку.
- Общий таймер для всех соединений. Ошибка на одной SMPP-сессии останавливает отправку по каналам, которые продолжают работать.
- Удаление исходной задачи. После временного отказа приложение теряет возможность повторить отправку и не может объяснить, куда исчезло SMS.
- Отсутствие журнала попыток. Без кода ошибки и времени повтора нельзя понять, что произошло с конкретным сообщением.
3 шага, которые можно сделать сегодня:
- Добавьте обработчики для
ESME_RTHROTTLEDиESME_RMSGQFUL, чтобы временные ошибки возвращали SMS в очередь. - Для throttling установите паузу 1 секунду на проблемном соединении, а для Message Queue Full ограничьте серию 3–5 повторными попытками.
- Сохраните код ошибки, номер попытки и итоговый статус в журнале, затем отдельно проверьте сценарии разрыва SMPP-сессии и отсутствия ответа.
