Настройка TCP-соединений: Keepalive, размер окна и алгоритм Нейгла
Настройка TCP-соединений: практическое руководство
TCP (Transmission Control Protocol) обеспечивает надёжную упорядоченную доставку данных по сети, но его настройки по умолчанию часто неоптимальны для современных приложений. Понимание и настройка параметров TCP может значительно улучшить пропускную способность, снизить задержки и оптимизировать использование ресурсов для ваших конкретных нагрузок.
Настройка TCP Keepalive
TCP keepalive — механизм обнаружения мёртвых соединений путём периодической отправки пробных пакетов при простое соединения. Без keepalive соединение может оставаться в состоянии ESTABLISHED бесконечно, даже после отключения удалённого хоста, бесполезно расходуя ресурсы.
Параметры Keepalive
| Параметр | Linux Sysctl | По умолчанию | Описание |
|---|---|---|---|
| Keepalive Time | net.ipv4.tcp_keepalive_time | 7200 с | Время простоя до отправки первого пробного пакета |
| Keepalive Interval | net.ipv4.tcp_keepalive_intvl | 75 с | Интервал между последующими пробными пакетами |
| Keepalive Probes | net.ipv4.tcp_keepalive_probes | 9 | Количество неудачных попыток до разрыва соединения |
Рекомендуемая настройка Keepalive
# Сокращение времени обнаружения для веб-серверов
# По умолчанию: 2 часа простоя до первого пробного пакета
# Настроено: 60 секунд простоя, 10-секундные интервалы, 6 попыток
# Мёртвое соединение обнаруживается за ~2 минуты вместо ~2.5 часов
sysctl -w net.ipv4.tcp_keepalive_time=60
sysctl -w net.ipv4.tcp_keepalive_intvl=10
sysctl -w net.ipv4.tcp_keepalive_probes=6
# Сохранение настроек после перезагрузки
echo "net.ipv4.tcp_keepalive_time = 60" >> /etc/sysctl.conf
echo "net.ipv4.tcp_keepalive_intvl = 10" >> /etc/sysctl.conf
echo "net.ipv4.tcp_keepalive_probes = 6" >> /etc/sysctl.conf
Размер TCP-окна и масштабирование
Окно приёма TCP определяет объём данных, которые могут находиться в пути до получения подтверждения. Для высокоскоростных соединений с большой задержкой (высокий BDP) размер окна по умолчанию часто является основным узким местом.
Произведение полосы пропускания на задержку
Оптимальный размер окна равен произведению полосы пропускания на задержку (BDP): ширина канала, умноженная на время кругового обхода. Для канала 1 Гбит/с с RTT 50 мс:
BDP = Bandwidth x RTT
BDP = 1 000 000 000 бит/с x 0,050 с = 50 000 000 бит = 6,25 МБ
# Окно приёма должно быть не менее 6,25 МБ для полного использования канала
Настройка масштабирования окна
# Включение масштабирования TCP-окна (окна больше 64 КБ)
sysctl -w net.ipv4.tcp_window_scaling=1
# Установка максимальных размеров буферов
sysctl -w net.core.rmem_max=16777216 # 16 МБ макс. буфер приёма
sysctl -w net.core.wmem_max=16777216 # 16 МБ макс. буфер отправки
# Диапазон авто-настройки TCP-буферов (мин, по умолч., макс)
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
Рекомендации по размеру буферов
- Веб-серверы — умеренные буферы (256 КБ - 1 МБ), достаточные для типичных HTTP-запросов и ответов
- Файловые серверы — большие буферы (4-16 МБ) для максимальной пропускной способности на высоких BDP
- Базы данных — умеренные буферы с акцентом на низкую задержку
- Приложения реального времени — маленькие буферы для минимизации bufferbloat и задержек
Алгоритм Нейгла
Алгоритм Нейгла сокращает количество мелких пакетов в сети, буферизуя небольшие записи и объединяя их в более крупные сегменты. Хотя это полезно для массовых передач, алгоритм может вносить задержки для интерактивных приложений или приложений реального времени.
Как работает алгоритм Нейгла
- Когда приложение записывает данные меньше MSS (Maximum Segment Size), TCP буферизует их
- Буферизованные данные отправляются только когда: предыдущий сегмент подтверждён, ИЛИ накоплено достаточно данных для заполнения MSS
- Это уменьшает число мелких пакетов, но добавляет до одного RTT задержки на каждую запись
Отключение алгоритма Нейгла
// C/C++ — отключение для сокета
int flag = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));
// Python — отключение для сокета
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
// PHP — отключение (при наличии расширения sockets)
socket_set_option($sock, SOL_TCP, TCP_NODELAY, 1);
Когда отключать алгоритм Нейгла
- Интерактивные протоколы — SSH, telnet, игры, где важна задержка нажатий
- Мультиплексирование HTTP/2 — маленькие фреймы не должны задерживаться
- Обмен сообщениями в реальном времени — чаты, WebSocket-соединения
- RPC-фреймворки — паттерны запрос-ответ с частыми мелкими сообщениями
Алгоритмы управления перегрузкой
Управление перегрузкой TCP определяет, насколько агрессивно TCP увеличивает скорость отправки. Современные алгоритмы значительно превосходят классические Reno и Cubic.
Сравнение алгоритмов
| Алгоритм | Оптимален для | Ключевая характеристика |
|---|---|---|
| Cubic | Общее назначение | По умолчанию в большинстве Linux, на основе потерь |
| BBR | Высокий BDP | На основе модели, независимо оценивает полосу и RTT |
| BBR2 | Справедливость | Улучшенная справедливость при совместной работе с Cubic |
| DCTCP | Дата-центры | Использует метки ECN для точного управления |
# Проверка доступных алгоритмов
sysctl net.ipv4.tcp_available_congestion_control
# Установка BBR по умолчанию (требуется ядро 4.9+)
sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq
Чек-лист оптимизации соединений
- Включите TCP Fast Open для сокращения времени установки повторных соединений
- Настройте параметры keepalive для быстрого обнаружения мёртвых соединений
- Рассчитайте BDP для основных сетевых путей и подберите размеры буферов
- Отключите алгоритм Нейгла для приложений, чувствительных к задержкам
- Рассмотрите BBR для сетей с высокой задержкой или потерями
- Включите выборочные подтверждения (SACK) для эффективного восстановления после потерь
- Установите подходящие тайм-ауты сокетов для предотвращения бесконечного ожидания
- Мониторьте частоту ретрансмиссий TCP и состояния соединений
Заключение
Настройка TCP — тонкая дисциплина, требующая понимания характеристик ваших нагрузок и сетевых условий. Универсальной оптимальной конфигурации не существует — правильные настройки зависят от приоритетов: пропускная способность, задержка или эффективность ресурсов. Начните с измерения текущей производительности TCP, определите узкие места через произведение полосы на задержку и применяйте точечную настройку с мониторинг сайтов результатов.
Проверьте ваш сайт прямо сейчас
Проверить →