PDU-лог SMPP — это сырой поток байтов между вашей системой и шлюзом: submit_sm, deliver_sm, enquire_link, ответы с кодами состояния. Если его разобрать вручную, можно увидеть, где именно сообщения застревают — на стороне клиента, канала связи или SMS-центра оператора. Ниже — практический путь: какие поля смотреть, какие ответы читать и как по логам находить узкое место доставки без платных анализаторов.
С чего начать разбор PDU-лога
PDU (Protocol Data Unit) в SMPP — это пакет фиксированного формата с заголовком и набором полей. В логе он выглядит как hex-строка или текстовая строка с полями через разделитель. Для диагностики хватает знания о пяти-шести полях: command_id, command_status, sequence_number, source_addr, destination_addr, short_message.
Первое, что стоит сделать, — собрать чистый лог за один тестовый прогон. Отправьте 50–100 тестовых сообщений на разные номера и запишите весь обмен в файл. Чем короче окно наблюдения, тем проще потом сопоставить отправку и ответ.
- Включите логирование на уровне библиотеки, через которую идёт SMPP-клиент.
- Сохраните обе стороны обмена: исходящие PDU и входящие ответы.
- Подпишите каждый пакет меткой времени с миллисекундами.
- Отфильтруйте шум: служебные enquire_link и unbind обычно не нужны для анализа доставки.
Какие коды ответов говорят о проблеме
Поле command_status в PDU — главный индикатор. Ноль означает, что шлюз принял сообщение. Любое другое значение — это код ошибки или статуса, описанный в SMPP-спецификации. Для диагностики узких мест в доставке полезно знать хотя бы базовые диапазоны:
- 0x00000000 — принято шлюзом, дальнейшая судьба сообщения зависит от DLR.
- 0x00000001–0x00000063 — системные ошибки отправителя или канала (таймаут сессии, переполнение окна).
- 0x00000008 — превышено значение throttling, то есть шлюз не успевает обрабатывать ваш поток.
- 0x0000000B — некорректный адрес назначения, отправка дальше не пойдёт.
- 0x00000014 — destination address blocked, отказ на уровне шлюза или оператора.
Если в логе массово появляется ошибка 0x08 — узкое место в вашем собственном потоке, шлюз физически не успевает. Если 0x14 — узкое место на стороне оператора или фильтра шлюза. Если нули идут подряд, а DLR не приходят — ищите проблему между шлюзом и SMSC.
Как читать тайминги в логе
Время между submit_sm и ответом — это первая задержка, которую видно. Время между submit_sm и первым DLR — это сквозная задержка доставки. Если первая задержка растёт, узкое место в канале или шлюзе. Если первая маленькая, а сквозная большая — узкое место у оператора или SMSC.
Практический приём: посчитайте разницу между timestamp отправки submit_sm и timestamp ответа submit_sm_resp с command_status = 0. Потом посчитайте разницу между submit_sm_resp и пришедшим deliver_sm с DLR. Первая разница покажет, как быстро шлюз забирает пакет. Вторая — как быстро оператор доставляет абоненту.
Какие поля показывают, где именно застряло сообщение
| Поле PDU | Что показывает |
|---|---|
| command_id | Тип пакета: submit_sm, deliver_sm, enquire_link |
| command_status | Код ошибки или подтверждение |
| sequence_number | Связывает запрос и ответ между собой |
| source_addr / destination_addr | Кто и кому, помогает фильтровать по базе |
| registered_delivery | Запрошены ли DLR и какие именно |
| short_message | Текст, помогает найти конкретную отправку |
По sequence_number легко склеить submit_sm и его submit_sm_resp, а затем найти соответствующий deliver_sm. Когда склейка собрана, видно полную цепочку одного сообщения: отправка — приём шлюзом — DLR о доставке. Если цепочка обрывается на одном из шагов — узкое место найдено.
Как связать лог с конкретной базой клиентов
Самый простой способ — добавить в каждое сообщение короткий тег в начале или в конце текста. По нему в логе вы найдёте конкретное submit_sm и поймёте, к какой рассылке или сегменту базы относится задержка. Альтернатива — вставить идентификатор клиента в поле source_addr или использовать нестандартное TLV-поле, если ваш шлюз поддерживает расширенные опции. Подробнее о работе с DLR-отчётами и привязке недоставок к базе — в материале Как отладить SMPP-сессию и читать PDU-логи без сложных платформ.
Если тег не нужен клиенту, его можно отрезать на уровне шлюза, но в логе он останется. Так вы получите и чистые сообщения, и привязку к базе для диагностики.
Типичные ошибки при ручном разборе лога
- Игнорировать поле registered_delivery. Без него DLR не приходят, и вы будете считать, что доставки нет.
- Смотреть только command_status и забыть про тайминги. Одинаковый ноль в статусе не означает одинаковую скорость доставки.
- Анализировать лог за сутки и путать всплески трафика с системной проблемой.
- Не отделять enquire_link от submit_sm. Служебные пакеты забивают лог и мешают увидеть реальную картину.
- Записывать только исходящий трафик и терять ответы шлюза, по которым видна основная диагностика.
- Менять параметры канала во время теста и не отмечать это в логе — потом невозможно понять, что повлияло.
Что делать, когда узкое место найдено
Когда в логах видно конкретное место задержки, дальнейшие шаги зависят от того, где оно возникло. Если шлюз возвращает ошибки 0x08, нужно снизить скорость отправки или запросить увеличение лимита. Если DLR не приходят вообще, проверьте registered_delivery и поддержку DLR на стороне оператора. Если задержка между submit_sm_resp и deliver_sm большая при нормальных кодах — это особенность сети оператора, и повлиять на неё с вашей стороны сложно.
Приоритезация транзакционного и маркетингового трафика на уровне шлюза помогает в моменты пик: коды авторизации и уведомления об операциях уходят первыми, рассылки ждут. Подробнее о настройке приоритетов — в материале Как настроить приоритет SMS-кодов в SMPP.
3 шага, которые можно сделать на этой неделе:
- Включить логирование обеих сторон SMPP-сессии с миллисекундными метками времени.
- Прогнать 50–100 тестовых сообщений и собрать сквозную цепочку submit_sm — submit_sm_resp — deliver_sm.
- Посчитать две задержки (до ответа шлюза и до DLR) и сравнить их по разным сегментам базы.



