Российские технологии и цифровая экономика
ПоискRSS

Cdn для Http-туннеля: почему потери запросов зависят от точки присутствия

5 минут чтения

CDN как транспорт для HTTP-туннеля: почему сначала обнаружились потери, а затем они исчезли

Кратко

За облачным CDN был размещён сервер Xray с транспортом XHTTP. Пользователи описывали проблему привычными словами: "тормозит" и "полностью отключается". В августе проверка показала: при параллельной нагрузке граница CDN иногда теряла от 2 до 5% запросов. Для режима packet-up это особенно критично: пропуск запроса нарушает последовательность и способен привести к разрыву сессии.

Однако 2 сентября тот же тест на том же стенде дал нулевой результат: 1350 запросов завершились успешно. Причина оказалась не в исправлении конфигурации, а в смене точки присутствия CDN. RTT до ближайшего PoP уменьшился с 37 до 17,6 мс, поэтому система фактически работала уже в других сетевых условиях.

Стенд и методика

В роли origin использовался Hetzner CX23 в Нюрнберге с 4 ГБ памяти. Nginx принимал соединения на порту 7443 и передавал их Xray, который слушал локальный адрес 127.0.0.1:4443. CDN подключался через CNAME поддомена, а заголовок Host подменялся на значение origin. Кэширование практически не применялось: ответы имели статус `Cache-Status: MISS`, что логично для туннельного трафика.

Xray работал с XHTTP в режиме `packet-up`, путь имел формат `/content/edge/fetch//`. Нагрузку создавали с отдельного сервера в Стокгольме. У него был симметричный канал и прямые маршруты до CDN и origin, поэтому результаты не зависели от пользовательского туннеля или нестабильного промежуточного маршрута.

Проверка выполнялась примерно 150 параллельными запросами `curl` с тайм-аутом 30 секунд. Учитывались HTTP-коды и код завершения самого клиента. Потерей считался `exit=28`, когда за отведённое время не поступал ни один ответ, а также редкие ответы 504. Для исправного туннельного пути нормальным маркером был ответ 400 с заголовком `X-Padding`.

Тем, кто изучает [настройку Xray XHTTP через CDN](https://habr.com/ru/articles/1080234/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1080234), важно заранее проверить метод uplink. XHTTP по умолчанию отправляет исходящий поток через POST, но используемый ресурс отвечал на POST кодом 405 Not Allowed. Это легко выявить: на заведомо отсутствующий путь origin возвращал 404, а CDN - 405. Следовательно, запрос блокировался на границе и до сервера не доходил. После переключения uplink на GET передача заработала. Возврат POST в конфигурацию в будущем снова создаст впечатление, будто CDN неисправен.

Первая серия измерений

12 августа результаты выглядели тревожно. На параллельной нагрузке доля неудачных запросов менялась от нуля до примерно 5%. При этом чёткой зависимости от числа одновременных соединений не обнаружилось: не было порога, после которого система начинала стабильно сыпаться.

Наибольший показатель - 5,4% - зафиксировали даже на обычном статическом файле, который не проходил через Xray. Это позволяло сделать важный вывод: если потери действительно существовали, причиной был не прокси и не логика туннеля.

Первые тесты с рабочего ноутбука давали разброс примерно в три раза. Позднее выяснилось, что сам ноутбук находился под туннелем, и маршрут выглядел как Финляндия → Москва → Нюрнберг. Такие измерения нельзя считать достоверными. Для сетевой диагностики требуется точка, из которой маршруты до CDN и origin максимально прямые. В корректном стенде RTT до PoP составлял 37 мс, а до origin - 26 мс.

Главная ошибка заключалась в интерпретации небольшого числа запусков. Три результата в диапазоне от 0 до 5% не означают, что средняя потеря равна 2,7%. Это лишь несколько наблюдений из неизвестного распределения. Вывод о стабильной характеристике системы оказался преждевременным.

Вторая серия и смена PoP

2 сентября использовались тот же сервер, та же команда и девять прогонов по 150 параллельных запросов. Всего было выполнено 1350 обращений - и ни одного потерянного.

Вероятность получить 1350 успешных запросов подряд при постоянной августовской доле потерь 2,7% равна:

`(1 − 0,027)^1350 ≈ e⁻³⁷`.

Настолько малая вероятность показывает: дело не в случайной удаче, а в изменившихся условиях работы.

Ответ оказался простым. RTT до точки присутствия CDN сократился с 37 до 17,6 мс. Клиента начал обслуживать другой PoP. Конфигурация ресурса и origin не менялись, зато изменилась инфраструктура на стороне провайдера.

Именно поэтому CDN для HTTP-туннеля нельзя оценивать по одному замеру. Распределённая сеть не имеет единого поведения: результат зависит от конкретного PoP, маршрута, времени суток, балансировки и текущего состояния пограничных узлов. Практически вы измеряете не "CDN вообще", а связку "клиент - выбранная точка присутствия - origin".

Четыре ограничения границы

Независимо от наличия потерь у границы CDN обнаружились ограничения, о которые HTTP-туннель способен регулярно спотыкаться.

Первое - метод POST. Если ресурс принимает только GET, стандартная конфигурация XHTTP будет получать 405 ещё до обращения к origin.

Второе - idle-тайм-аут. На границе соединение простаивало около 15 секунд, тогда как origin допускал примерно 75 секунд. Поэтому длинная пауза внутри туннеля могла восприниматься как разрыв, хотя сервер продолжал считать сессию активной.

Третье - максимальный размер тела запроса: ровно 1 MiB, до последнего байта. Любая передача крупнее упиралась в ограничение CDN, даже если сервер за ним мог принять больше.

Четвёртое - хрупкость режима packet-up. Для него важна последовательность запросов, поэтому единичный пропуск способен разрушить логический поток. В обычном веб-приложении кратковременный сбой мог бы быть незаметен или компенсирован повтором, а в HTTP-туннеле последствия оказываются гораздо серьёзнее.

Практические выводы

Если требуется понять, [как настроить CDN для прокси-сервера](https://habr.com/ru/articles/1080234/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1080234), начинать следует не с подбора параметров Xray, а с проверки поведения самой границы. Нужно отдельно протестировать GET и POST, малые и большие тела, длительные простои, коды ошибок и фактический маршрут до разных PoP.

Полезно проводить серию тестов в разное время и из нескольких независимых сетей. Один запуск не показывает устойчивость сервиса, а среднее значение по нескольким случайным точкам может скрыть переключение между узлами. В отчёте стоит фиксировать RTT, IP-адрес CDN, заголовки ответа, регион PoP и временной интервал.

Для более точной диагностики потерь пакетов через CDN следует разделять уровни проблемы. Сначала проверяется обычный статический файл, затем простой HTTP-запрос без Xray и лишь после этого - туннельный режим. Если сбои видны уже на статике, искать причину в packet-up бессмысленно.

Наконец, защита и ускорение HTTP-туннеля через CDN не сводятся к маскировке адреса origin. CDN может снизить задержку для части пользователей, скрыть инфраструктуру и упростить масштабирование, но одновременно добавить собственные тайм-ауты, ограничения размера тела и зависимость от маршрутизации. Поэтому перед эксплуатацией необходимо проверить не только пропускную способность, но и поведение при простое, повторных подключениях и смене точки присутствия.

Главный результат эксперимента оказался методологическим: нельзя превращать несколько неустойчивых измерений в постоянную характеристику сети. В распределённой инфраструктуре корректный вывод должен учитывать маршрут, конкретный PoP и условия теста. Иначе временная особенность одного узла легко будет принята за системную проблему всего CDN.

Прокрутить вверх