IT-инфраструктура • инструкции • практикаПоиск по сайту

Серверы и системное администрирование

Найти материал

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

CDN для HTTP-туннеля: почему в одном регионе мы увидели 5% потерь, а через три недели - ноль

За облачным CDN у нас работал Xray с транспортом XHTTP. Пользовательские жалобы сводились к двум формулировкам: соединение "тормозит" или внезапно "отваливается насовсем". В августе тесты показали от 2 до 5% потерянных запросов при параллельной нагрузке. Однако повторная проверка через три недели дала совершенно иной результат: ни одной ошибки на 1350 запросах.

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

Тестовый стенд и схема подключения

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

Кэширование фактически не участвовало в эксперименте: во всех ответах присутствовал `Cache-Status: MISS`. Для туннельного трафика это логично - кэшировать потоковые запросы не требуется и, скорее, вредно.

Использовался XHTTP в режиме `packet-up` с путём формата `/content/edge/fetch//`. Нагрузку генерировали с отдельного сервера в Стокгольме. У него был симметричный канал и прямые маршруты как до CDN, так и до origin. Это оказалось принципиально важно: первые измерения с рабочего ноутбука давали разброс примерно втрое выше, поскольку сам ноутбук уже находился под туннелем, а трафик шёл по маршруту Финляндия → Москва → Нюрнберг.

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

Сначала нужно проверить сам метод

До запуска массовых тестов обнаружилась настройка, которая легко маскируется под неисправность CDN. XHTTP по умолчанию отправляет uplink через POST, а выбранный ресурс отвечал на POST кодом 405 Not Allowed.

Проверка была простой: использовался заведомо несуществующий путь. Origin возвращал 404, а CDN - 405. Это означало, что запрос до сервера назначения не доходил вовсе: его отклоняла граница CDN. После переключения uplink на GET туннель начал работать нормально. Если позднее вернуть POST, конфигурация снова перестанет функционировать, а внешне проблема будет выглядеть как отказ CDN.

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

Августовская серия: нестабильные 2-5%

В первой серии наблюдались потери, но они вели себя необычно. Их доля не увеличивалась вместе с числом параллельных запросов. Не удалось найти и порог, после которого система начинала "сыпаться": при одинаковой нагрузке один прогон показывал нулевой результат, а другой - до 5% ошибок.

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

Главная методологическая ошибка состояла в том, что три запуска с результатами от 0 до 5% попытались интерпретировать как среднее значение 2,7%. Но трёх точек недостаточно, чтобы описать распределение. Корректнее было сказать: система демонстрирует нестабильный результат, причина которого пока не установлена.

Сентябрьская серия: 1350 успешных запросов

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

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

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

Это практически невозможное совпадение. Следовательно, результат нельзя объяснить случайной удачей: условия обработки действительно изменились.

Причина нашлась быстро. Запросы начали обслуживаться другим PoP, а задержка до точки присутствия сократилась с 37 до 17,6 мс. Конфигурацию CDN и origin между тестами не меняли. Изменилось только то, какая площадка распределённой сети принимала трафик.

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

Ограничения, которые сохранились в обеих сериях

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

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

Третье ограничение - максимальный размер тела запроса. Он составлял ровно 1 MiB, до последнего байта. Любой сценарий, предполагающий передачу более крупного блока, требовал предварительного дробления данных или изменения архитектуры.

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

Практические выводы для эксплуатации

Тем, кто изучает, как настроить CDN для прокси-сервера, стоит начинать не с высокой параллельной нагрузки, а с базовой матрицы проверок: методы GET и POST, существующие и несуществующие пути, разные размеры тела, длительное бездействие и повторное открытие соединения. Такая последовательность помогает отличить ошибку конфигурации от сетевой нестабильности.

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

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

Главный результат эксперимента оказался шире конкретной проблемы Xray. У распределённой сети нет единого поведения, которое можно измерить одним запуском. Любой замер описывает сочетание конкретного клиента, маршрута, PoP, времени суток и текущего состояния инфраструктуры. Поэтому один тест может показать 5% потерь, а повторный - абсолютный ноль, не будучи ошибочным ни в одном из случаев.

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