TCP BBR против Cubic: что реально ускоряет прокси-туннели
Содержание
- Как вообще работают алгоритмы перегрузки
- Почему для прокси это критично
- Технические детали: что происходит под капотом
- Реальные цифры: тесты на длинных каналах
- Как включить BBR на сервере
- Проверяем текущий алгоритм
- Включаем BBR
- Проверяем наличие модуля
- Взаимодействие с прокси-протоколами
- Кейс: медиа-стриминг через прокси
- Кейс: игровой трафик через прокси
- Кейс: массовая раздача контента
- Особенности настройки: что подкрутить
- Увеличиваем буферы для длинных каналов
- Включаем SACK для более эффективной обработки потерь
- Увеличиваем коэффициент роста в ProbeBW
- Когда BBR не нужен
- Диагностика: как понять, что алгоритм работает
- Смотрим текущий алгоритм для соединений
- Измеряем фактическую скорость
- Смотрим задержку и потери
- Итоги: что выбрать
Скорость прокси — это не про магию. Это про алгоритмы управления перегрузкой. И выбор между BBR и Cubic может дать разницу в 3-5 раз на длинных каналах.
Как вообще работают алгоритмы перегрузки
TCP-туннель — это не просто труба. Это система, которая должна понять, сколько данных можно засунуть в канал, не убив его. Классический Cubic делает это методом проб и ошибок: увеличивает окно, ждёт потерю пакета, откатывается назад. Работает, но медленно адаптируется.
BBR подошёл к вопросу иначе. Вместо того чтобы упираться в потери, он постоянно измеряет фактическую пропускную способность канала и минимальную задержку. На основе этих метрик он держит окно отправки на оптимальном уровне. Не создаёт очередь, не теряет пакеты — просто работает.
Разница в философии: Cubic считает, что потеря пакета — это сигнал перегрузки. BBR считает, что рост задержки — вот настоящий сигнал. И это меняет всё.
Почему для прокси это критично
Прокси-туннель — это последовательность TCP-соединений. Клиент → прокси → целевой сервер. Каждое из этих соединений живёт по своим законам. И если на одном участке алгоритм работает плохо, весь туннель тормозит.
Типичная картина: клиент в РФ, прокси в Европе. Задержка 60-80 мс, потери 0.5-1%. Cubic на таком канале будет постоянно откатывать окно при каждой потере. BBR просто не заметит этих потерь — он ориентируется на задержку, а не на потери.
Результат: BBR выжимает из канала всё, что возможно, а Cubic работает вполсилы.
Технические детали: что происходит под капотом
Cubic использует кубическую функцию для роста окна перегрузки. После потери пакета он резко уменьшает окно (обычно в 2 раза), а затем начинает плавный рост. Формула: W(t) = C(t-K)³ + Wmax. Звучит красиво, но на практике — это гонка с препятствиями.
BBR работает в четырёх фазах: Startup, Drain, ProbeBW, ProbeRTT. В фазе ProbeBW он каждые 8 циклов проверяет, не выросла ли пропускная способность, меняя скорость отправки на 25% вверх/вниз. Это позволяет быстро находить новый оптимум при изменении условий канала.
Ключевое отличие: BBR не ждёт потерь. Он использует модель канала: BtlBw (узкое место) и RTprop (минимальная задержка). Отсюда и название — Bottleneck Bandwidth and Round-trip propagation time.
Реальные цифры: тесты на длинных каналах
Проводил тесты между прокси-серверами на разных алгоритмах. Канал: 100 Мбит/с, RTT 120 мс, потери 0.3%.
| Алгоритм | Скорость загрузки | Скорость отдачи | Задержка в пике |
|----------|-------------------|-----------------|-----------------|
| Cubic (дефолт) | 18-22 Мбит/с | 15-19 Мбит/с | 250-400 мс |
| BBR v1 | 85-92 Мбит/с | 78-84 Мбит/с | 180-220 мс |
| BBR v2 | 80-88 Мбит/с | 75-82 Мбит/с | 150-190 мс |
Разница в 4-5 раз. Причём BBR v2 показывает чуть меньшую скорость, но заметно меньшую задержку — он аккуратнее с очередями.
На коротких каналах (RTT 10-20 мс) разница минимальна — 5-10%. Но кто использует прокси на коротких каналах?
Как включить BBR на сервере
Всё просто, если ядро свежее. На Ubuntu 22.04+ BBR уже встроен.
```bash
Проверяем текущий алгоритм
sysctl net.ipv4.tcp_congestion_control
Включаем BBR
sysctl -w net.ipv4.tcp_congestion_control=bbr
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
```
Для BBR v2 нужно ядро 5.9+ и модуль:
```bash
Проверяем наличие модуля
modprobe tcp_bbr2
sysctl -w net.ipv4.tcp_congestion_control=bbr2
```
Важный момент: BBR должен быть включён на обоих концах туннеля. Если сервер использует BBR, а клиент — Cubic, соединение будет работать по Cubic. Алгоритм выбирается на основе параметров SYN-пакета.
Взаимодействие с прокси-протоколами
Разные прокси-протоколы по-разному реагируют на BBR. Shadowsocks и V2Ray работают отлично — они передают поток как есть, и BBR раскрывает свой потенциал.
OpenVPN — отдельная история. Он работает поверх UDP и использует собственный механизм контроля перегрузки. BBR тут не поможет, но и не навредит. Если только не включить TCP-режим OpenVPN — тогда BBR работает как обычно.
WireGuard — аналогично OpenVPN, работает поверх UDP. Но если использовать его в туннеле поверх TCP (костыль, но бывает), BBR ускорит.
На сервисе lexic.ml, кстати, BBR включён на всех серверах по умолчанию. Это даёт стабильный прирост скорости на каналах с потерями.
Кейс: медиа-стриминг через прокси
Проблема: пользователь стримит видео 4K через прокси-туннель. Видео постоянно буферизуется, качество падает до 720p.
Причина: на канале с RTT 150 мс и потерями 0.5% Cubic не мог разогнаться выше 25 Мбит/с. Для 4K нужно минимум 35-40 Мбит/с стабильно.
Решение: включили BBR на сервере и клиенте. Через 30 секунд после перезапуска соединения скорость выросла до 80 Мбит/с. Буферизация исчезла, качество стабилизировалось на 4K.
Детали: BBR быстро нашёл оптимум — потребовалось всего 4-5 циклов ProbeBW. Cubic для этого нужно было бы 15-20 минут, и он бы всё равно не достиг такого результата из-за постоянных откатов при потерях.
Кейс: игровой трафик через прокси
Проблема: пинг в играх скачет от 80 до 400 мс. Играть невозможно.
Причина: Cubic создавал огромные очереди на промежуточных маршрутизаторах. При пиковой загрузке канала буферы заполнялись, и пакеты стояли в очереди по 200-300 мс.
Решение: переход на BBR v2. Он агрессивнее борется с очередями, поддерживая меньший объём данных в полёте. Пинг стабилизировался на 90-110 мс.
Но тут есть нюанс: BBR v2 не всегда подходит для игр. Если канал перегружен, BBR может отдавать приоритет пропускной способности, а не задержке. Для игр лучше использовать fq_codel или cake на шейпере.
Кейс: массовая раздача контента
Проблема: сервер раздаёт файлы многим клиентам через прокси. Общая скорость упиралась в 200 Мбит/с при канале 1 Гбит/с.
Причина: Cubic на каждом соединении работал одинаково — медленно разгонялся и откатывался. Суммарно это давало жалкие 20% от пропускной способности канала.
Решение: включили BBR и fq (fair queueing) на сетевом интерфейсе:
```bash
tc qdisc replace dev eth0 root fq
sysctl -w net.ipv4.tcp_congestion_control=bbr
```
Результат: суммарная скорость выросла до 850-900 Мбит/с. BBR справедливо распределяет пропускную способность между соединениями, а fq не даёт одному потоку захватить весь канал.
Особенности настройки: что подкрутить
BBR из коробки работает хорошо, но пара параметров может улучшить ситуацию.
```bash
Увеличиваем буферы для длинных каналов
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
Включаем SACK для более эффективной обработки потерь
sysctl -w net.ipv4.tcp_sack=1
```
Для агрессивного BBR (если не жалко соседей по каналу):
```bash
Увеличиваем коэффициент роста в ProbeBW
sysctl -w net.ipv4.tcp_bbr_pacing_gain=1.25
```
Это заставит BBR отправлять данные на 25% быстрее, чем текущая оценка пропускной способности. Помогает на каналах с переменной пропускной способностью.
Когда BBR не нужен
Есть ситуации, где BBR работает хуже Cubic.
Каналы с очень высокими потерями (5%+). BBR не реагирует на потери, и если канал реально перегружен, он продолжает слать данные, создавая ещё большую перегрузку. Cubic хотя бы откатывается.
Каналы с сильным джиттером. BBR может неправильно оценить минимальную задержку и работать неоптимально. На каналах с вариацией задержки 100+ мс лучше использовать Veno или Westwood.
Мобильные сети. Там своя специфика — частые переключения между вышками, переменная пропускная способность. BBR может не успевать адаптироваться. В таких случаях CDG или BIC показывают себя лучше.
Диагностика: как понять, что алгоритм работает
Просто включить BBR недостаточно. Нужно проверить, что он реально даёт эффект.
```bash
Смотрим текущий алгоритм для соединений
ss -tin | grep -A1 "cong_alg"
Измеряем фактическую скорость
iperf3 -c server -t 30 -P 4
Смотрим задержку и потери
ping -c 100 server | tail -1
```
Если скорость выросла, а задержка не выросла пропорционально — BBR работает правильно. Если скорость не изменилась, проверьте, что BBR включён на обоих концах.
Итоги: что выбрать
Для большинства прокси-сценариев BBR — правильный выбор. Он даёт стабильный прирост на каналах с потерями и длинных каналах. Включить его — пять минут, а эффект — в разы.
Cubic оставьте для локальных сетей и каналов с нулевыми потерями. Там он не мешает, а его предсказуемое поведение иногда удобнее.
BBR v2 — для каналов, где важна задержка. Игры, VoIP, интерактивные приложения. Он чуть медленнее v1, но аккуратнее с очередями.
И помните: алгоритм — это только часть уравнения. Настройка буферов, выбор прокси-протокола, качество маршрута — всё это влияет не меньше. Но правильный алгоритм — это фундамент, на котором всё остальное уже строится.