Три оси формы трафика: почему два механизма требуют противоположного
Инженер, настраивающий транспорт против современных ограничений, довольно быстро упирается в неприятное: два задокументированных механизма требуют взаимно исключающих настроек. Одно требует держать соединения долго и переиспользовать их, другое — наоборот, менять чаще. Противоречие снимается, как только становится видно, что механизмы считают разные величины, а не одну и ту же.
Разберём, где проходит настоящая граница.
Два механизма#
Объёмное ограничение. Соединение позволяет передать порядка шестнадцати килобайт, после чего поток встаёт. Учёт ведётся на одно TCP-соединение. Cloudflare публично описал это поведение с 9 июня 2025 года; в сообществе оно обсуждалось как «TCP 16-20», а позже было переименовано с уточнением, что лимит применяется и к TCP, и к UDP.
Очевидная контрмера: дробить. Много коротких соединений, каждое не доходит до порога.
Ограничение параллелизма. Несколько одновременных защищённых соединений к одному адресу в коротком окне вызывают срабатывание, после которого новые попытки не проходят некоторое время.
Очевидная контрмера: сливать. Мало соединений, много потоков внутри каждого.
Настройки прямо противоположны. Классическая реакция — выбрать, какой механизм терпеть.
Почему противоречие кажущееся?#
Оно исчезает, если заметить, что «много соединений» — не одна величина, а две. Одна величина — сколько соединений открыто за период, вторая — сколько их живёт одновременно, и механизмы считают их порознь.
| Ось | Что ограничивает объёмный механизм | Что ограничивает механизм параллелизма |
|---|---|---|
| Соединений всего за сессию | нужно много | безразлично |
| Соединений одновременно | безразлично | нужно мало |
| Байт на соединение | нужно мало | безразлично |
Первый механизм ограничивает накопленный объём. Второй — скорость открытия. Это разные величины, и они конфликтуют только если открывать соединения пачками.
Плавная ротация удовлетворяет обоим: много соединений последовательно, но никогда больше двух-трёх одновременных рукопожатий. Количество набирается во времени, а не в моменте.
Ротация во времени не равна параллелизму в моменте — и вся развязка держится на этом различии.
Разбор: пачка против плавной ротации#
Разница между двумя способами набрать одно и то же количество соединений — на временной шкале.
ПАЧКОЙ — срабатывает ограничение параллелизма
время → 0мс 100мс 200мс 300мс 400мс
│ │ │ │ │
соед. 1 ├─────────────────────────────────►
соед. 2 ├─────────────────────────────────► 4 одновременных
соед. 3 ├─────────────────────────────────► рукопожатия
соед. 4 ├─────────────────────────────────► в окне 400 мс
▲
└── порог превышен здесь
ПЛАВНО — то же количество, ограничение не срабатывает
время → 0с 3с 6с 9с 12с
│ │ │ │ │
соед. 1 ├──────────►│
соед. 2 ├──────────►│ не более 1–2
соед. 3 ├──────────►│ одновременно
соед. 4 ├──────────►│ в любой момент
Соединений в обоих случаях четыре. Различается только распределение во времени.
Нижний вариант удовлетворяет оба механизма сразу: количество набирается — значит ни одно соединение не копит объём; одновременность низкая — значит порог параллелизма не достигается.
Числовой пример: где именно ломается односторонняя настройка#
Возьмём загрузку в 2 МБ и посчитаем три конфигурации.
| Настройка | Соединений | Байт на соединение | Одновременно | Итог |
|---|---|---|---|---|
| «Мало соединений, много потоков» | 2 | ~1 000 000 | 2 | ❌ объёмное ограничение на 16 КБ |
| «Много соединений, мало потоков» | 130 | ~16 000 | 8 | ❌ порог параллелизма |
| Плавная ротация | 130 | ~16 000 | 2 | ✅ оба порога не достигнуты |
Первая строка — типовая рекомендация против ограничения параллелизма. Она даёт по мегабайту на соединение, то есть превышает объёмный порог в шестьдесят раз.
Вторая — типовая рекомендация против объёмного ограничения. Объём в норме, но восемь одновременных рукопожатий превышают порог параллелизма.
Третья отличается от второй только одним параметром — сколько соединений держится открытыми в один момент. Количество, объём и время те же.
Это и есть практический смысл разделения на оси: третья конфигурация не является компромиссом между первыми двумя. Она удовлетворяет оба ограничения полностью, потому что они ограничивают разные величины.
Где развязка упирается в предел#
Красиво в теории, ограниченно на практике — по конкретной причине.
Транспорты, дающие мультиплексирование поверх HTTP, обычно позволяют настроить, когда переоткрывать нижележащее соединение. Но триггеры ротации почти всегда временны́е и по числу запросов, а не по объёму.
Задать «переоткрывать после пятнадцати килобайт» напрямую нельзя. Приблизить — можно, снижая допустимое число запросов на соединение, но это косвенная регулировка величины, которая считается в байтах.
Именно поэтому в трекере Xray с июня 2025 года висит открытый запрос на дробление нисходящего потока по разным TCP-соединениям заданного размера. Автор запроса — тот же человек, который описал механизм, — оценивает цену честно: около двух с половиной тысяч TCP-соединений на файл в пятьдесят мегабайт, что «много и довольно подозрительно, но явно лучше, чем не работать вообще».
Запрос до сих пор не реализован. Параметрический тюнинг здесь паллиатив, а не решение.
Распространённая ошибка: дробление не на том уровне#
Отдельно стоит назвать ловушку, в которую попадают многие.
Транспорты вроде XHTTP умеют разбивать передачу на множество HTTP-запросов. Возникает соблазн считать, что это и есть дробление против объёмного ограничения.
Не является. Если все эти запросы идут внутри одного TCP-соединения, счётчик механизма — а он считает по TCP-соединению — продолжает расти. Автор механизма формулировал это прямо: разделение на несколько HTTP-запросов в одном соединении — это другое, и оно не поможет.
Полезное следствие для проверки любой настройки: смотрите, на каком уровне происходит дробление. Если на прикладном, а счётчик на транспортном — вы не решили задачу, а замаскировали её от себя.
Ещё одна ловушка: односторонняя оптимизация#
Обе очевидные контрмеры односторонни, и обе встречаются в готовых рекомендациях.
Настройка «одно-два соединения, много потоков в каждом» правильна против параллелизма и худшая возможная против объёма: потоки сводятся в минимум соединений и наполняют каждое быстрее всего.
Обратная — «много соединений, мало потоков» — правильна против объёма и провоцирует срабатывание по параллелизму.
Готовые наборы параметров из обсуждений обычно оптимизированы против одного механизма, потому что автор наблюдал именно его. Перенос такого набора в другие условия даёт результат хуже, чем настройка по умолчанию.
Что из этого практически применимо#
Помечайте каждый параметр осью. Параметр формы потока, заданный без указания, что именно он ограничивает — количество, одновременность или объём, — не является решением. Он является догадкой.
Проверяйте, что измеряете. Один и тот же симптом «не работает» порождается обоими механизмами, и различаются они только по признаку: объёмный даёт остановку после N килобайт, параллельный — отказ новых соединений при живом старом.
Не переносите числа между условиями. Пороги наблюдались разными людьми на разных операторах в разное время. Числовой порог из внешнего источника разумно считать гипотезой, а в конфигурации выражать диапазоном, а не константой.
Вывод#
Противоречие между двумя механизмами существует только в формулировке «много или мало соединений». Как только величина разделяется на количество, одновременность и объём, обе задачи оказываются решаемыми одновременно.
Но у развязки есть потолок: триггеры ротации не байтовые, и пока в транспортах нет дробления по объёму, параметрическая настройка остаётся приближением. Знать её предел важнее, чем найти удачный набор чисел, — потому что набор чисел устаревает вместе с наблюдением, а понимание осей нет.
Термины#
- Ось количества - сколько соединений открыто за период — величина, которую считает один из механизмов.
- Ось одновременности - сколько соединений живёт параллельно в один момент времени.
- Ось объёма на соединение - сколько байт передано в пределах одного соединения до срабатывания ограничения.
FAQ: частые вопросы#
Держать соединения долго или менять чаще?#
Ни то ни другое в чистом виде. Плавная ротация удовлетворяет обоим механизмам: соединения меняются, но не пачкой и не поодиночке.
Почему односторонняя настройка проигрывает?#
Она оптимизирует одну ось и ухудшает другую. Механизмы считают разные величины, поэтому выигрыш по одной оплачивается проигрышем по второй.
Есть ли предел у такой развязки?#
Да. При достаточно большом трафике обе оси упираются в свои потолки одновременно, и компромисса, удовлетворяющего обоим, не остаётся.
Что читать дальше#
- Тихие отказы: когда отвергает сервер, а выглядит как блокировка
- Как измерять блокировку правильно
- Гайд по Xray-core
- Пройдите маршрут от настройки до диагностики в VPN-гайдах GigaTap.
- Выберите следующий шаг с помощью помощника VPN start.
- Импорт профиля под конкретное устройство — в хабе настройки клиентов.