Почему скорость через прокси скачет: TCP путает плохую связь с перегрузкой

Почему скорость через прокси скачет: TCP путает плохую связь с перегрузкой

Если скорость через прокси то нормальная, то вдруг падает в разы без видимой причины — чаще всего дело не в самом прокси, а в том, как протокол TCP реагирует на потерю пакетов. TCP не умеет отличать «сеть перегружена» от «канал просто нестабильный», и в обоих случаях реагирует одинаково — резко снижает скорость передачи. На мобильных и части резидентских сетей потери пакетов — это норма физики канала, а не признак перегрузки, но TCP всё равно их штрафует.

Как TCP разгоняется: медленный старт

Каждое новое TCP-соединение начинает с маленького окна передачи и наращивает его по алгоритму медленного старта — экспоненциально, пока не случится первая потеря или пока окно не достигнет порога, после чего рост становится линейным (фаза предотвращения перегрузки). Это значит, что полную скорость канала соединение получает не сразу, а через несколько раундов обмена. Короткие запросы — например, парсинг небольшого количества страниц новыми соединениями каждый раз — просто не успевают разогнаться до пика скорости и работают на заниженной пропускной способности почти всё время жизни соединения.

Потеря пакета как ложный сигнал «притормози»

TCP исходит из простого допущения: если пакет потерян, где-то в сети переполнился буфер маршрутизатора — значит, надо снизить скорость передачи. При тройном дублирующем подтверждении (получатель трижды подряд подтверждает один и тот же пакет, сигнализируя о пропуске) TCP уменьшает окно вдвое и запускает быстрое восстановление. При таймауте — реагирует ещё жёстче и сбрасывает окно к минимуму, снова запуская медленный старт. Проблема в том, что причиной потери необязательно является перегрузка: пакет может быть искажён и отброшен из-за помех в радиоканале, и тогда TCP «наказывает» соединение за то, в чём сеть не виновата.

Мобильная связь и резидентские сети: физика против логики TCP

Беспроводной канал по своей природе шумнее проводного: затухание сигнала, многолучевое распространение, интерференция с другими устройствами — всё это увеличивает частоту битовых ошибок и, соответственно, отброшенных пакетов на канальном уровне. Для мобильных прокси это означает, что даже при свободной сети TCP-сессия периодически «спотыкается» об одиночные потери и снижает окно — просто потому, что физика радиоканала не идеальна. То же самое, но в меньшей степени, касается части резидентских узлов на нестабильном домашнем Wi-Fi или слабом DSL-канале: колебания качества соединения конечного устройства TCP интерпретирует как сигналы о перегрузке сети.

RTT и почему он умножается на число хендшейков

Время оборота (RTT — round-trip time) — это время от отправки пакета до получения подтверждения. Каждое новое TCP-соединение требует минимум одного RTT на трёхстороннее рукопожатие, ещё один RTT добавляет TLS-хендшейк для HTTPS, и только после этого начинается передача полезных данных. Если приложение открывает новое соединение на каждый запрос вместо переиспользования уже установленного, оно платит этот RTT-налог заново каждый раз — а на мобильном канале с типичным RTT в разы выше, чем у проводного, это ощущается особенно заметно.

Разброс потерь и задержки по типам сети

Тип каналаОсновной источник потерьРеакция TCPЧто это даёт на практике
Серверный (дата-центр)Реальная перегрузка канала/буфераОправдана — снижение скорости действительно разгружает сетьСтабильная, предсказуемая скорость
ISP / резидентский на проводном доступеИзредка — качество линии, домашнее оборудованиеВ основном оправданаУмеренные, редкие просадки
Резидентский на Wi-FiИнтерференция, расстояние до роутераЧастично излишняяЗаметный разброс скорости в течение дня
Мобильный (3G/4G)Радиопомехи, хэндовер между сотамиВ основном излишняяНаибольшая волатильность скорости и RTT

Точные цифры потерь и RTT сильно различаются по региону, оператору и времени суток — если для конкретной задачи важны гарантии по этим метрикам, их стоит замерить на своём трафике, а не ориентироваться на усреднённые оценки.

Что реально чинится на вашей стороне

  1. Переиспользуйте соединения (keep-alive). Если инструмент для запросов позволяет держать TCP/TLS-соединение открытым между запросами к одному хосту, это убирает повторный RTT-налог на хендшейк для каждого следующего запроса.
  2. Не разгоняйте параллельность бездумно. Слишком много одновременных соединений через один и тот же нестабильный узел заставляет каждое из них конкурировать за пропускную способность и чаще ловить потери — иногда 5 стабильных потоков быстрее, чем 50 конкурирующих.
  3. Настройте разумные ретраи с задержкой (backoff), а не мгновенный повтор. Мгновенный повтор на том же нестабильном узле почти наверняка повторит ту же проблему.
  4. Разделяйте задачи по типу прокси. Для стабильности по скорости — серверные или ISP-прокси; для устойчивости к блокировкам ценой большего разброса скорости — мобильные и резидентские.

Как это устроено у нас

Если задаче важна именно стабильность скорости — присмотритесь к серверным IPv4-прокси или ISP-прокси: там нет случайных радиопомех, а колебания RTT минимальны. Там, где важнее не попасть под блокировку по IP, а не пиковая скорость — мобильные прокси и резидентские прокси остаются осознанным компромиссом, а не браком. Для промышленного сбора данных с предсказуемой нагрузкой полезно посмотреть кейс «Прокси для парсинга».

Частые вопросы

Значит ли это, что мобильные прокси всегда медленнее серверных?
В среднем — да, по пиковой скорости и стабильности. Но задача мобильных прокси не в максимальной скорости, а в устойчивости к блокировкам по IP, и здесь они выигрывают за счёт устройства carrier-grade NAT у оператора.

Можно ли заставить TCP не снижать скорость при потере пакета?
Напрямую и безопасно — нет, это базовый механизм защиты сети от перегрузки. Но можно уменьшить число потерь на своей стороне (стабильное соединение, меньше избыточной параллельности) и минимизировать эффект от каждой отдельной потери за счёт переиспользования соединений.

Почему один и тот же прокси то быстрый, то медленный в разное время суток?
Чаще всего — из-за загрузки канала на стороне устройства-донора (для резидентских и мобильных прокси) в часы пик, когда через тот же канал одновременно идёт и обычный трафик реального пользователя.

Помогает ли HTTP/2 или HTTP/3 в этой ситуации?
HTTP/2 переиспользует одно TCP-соединение для многих запросов, что снижает число хендшейков. HTTP/3 идёт дальше и работает поверх QUIC (на UDP), где механизм реакции на потери устроен иначе и лучше переживает нестабильные каналы, но поддержка зависит от целевого сайта и инструментов на вашей стороне.

Как понять, что проблема именно в TCP, а не в самом прокси-сервере?
Косвенный признак — просадка скорости коррелирует с единичными таймаутами или повторными передачами, а не держится постоянно на низком уровне. Полная и стабильно низкая скорость с самого начала сессии чаще говорит о проблеме на стороне сервера или канала, а не о поведении протокола.

Источники

Kurose J., Ross K. Computer Networking: A Top-Down Approach, 6th Edition — разделы о надёжной передаче данных и управлении перегрузкой TCP (медленный старт, предотвращение перегрузки, быстрое восстановление); RFC 5681 (TCP Congestion Control).

Не уверены, какой тип прокси даст нужный баланс скорости и стабильности под вашу задачу? Опишите сценарий менеджеру Proxy.Market — подберём пул, а не посоветуем «попробовать и посмотреть».