На производительность nginx очень большое влияние имеет настройка ОС.
В данной статье затронуты некоторые очень важные аспекты настройки ОС Linux, в частности Ubuntu 12.04 для достижения максимальной производительности сетевой подсистемы.
Внесите следующие изменения в /etc/sysctl.conf
, чтобы применить изменения выполните команду sysctl -p
.
Увеличим длину очереди для входящих пакетов. Значение 30000 это нормальное значение даже для 10GigE, если у Вас входящий канал не превышает 1Gbit/s, то выставлять значение переменной netdev_max_backlog более 10000 не имеет смысла.
1 |
net.core.netdev_max_backlog=10000 |
Сделать это можно внеся изменения в /etc/sysctl.conf
, как уже говорилось:
1 |
echo 'net.core.netdev_max_backlog = 10000' >> /etc/sysctl.conf |
или на ходу:
1 |
sysctl –w net.core.netdev_max_backlog=10000 |
или так
1 |
echo 10000 > /proc/sys/net/core/netdev_max_backlog |
Посмотреть текущее значение:
1 |
cat /proc/sys/net/core/netdev_max_backlog |
Далее увеличиваем количество возможных подключений к сокету аналогичным образом. По умолчанию значение равно 128, что при высоко нагруженном сервере будет являться узким местом.
1 |
net.core.somaxconn=262144 |
Включаем tcp_syncookies, эта опция необходима для того, чтобы вы могли использовать параметрnet.ipv4.tcp_max_syn_backlog
описанный ниже.
1 |
net.ipv4.tcp_syncookies=1 |
Увеличиваем буфер под хранение SYN запросов на соединение. Значение по умолчанию 1024, что очень мало для нагруженных серверов.
1 |
net.ipv4.tcp_max_syn_backlog = 262144 |
Увеличим возможное количество сокетов в состоянии TIME_WAIT
1 |
net.ipv4.tcp_max_tw_buckets = 720000 |
Разрешаем быструю утилизацию сокетов находящихся в состоянии TIME_WAIT
1 |
net.ipv4.tcp_tw_recycle = 1 |
Включаем tcp_timestamps иначе не будет работать опция tcp_tw_reuse
описанная ниже
1 |
net.ipv4.tcp_timestamps = 1 |
Включаем механизм разрешающий использовать уже существующие сокеты, которые находятся в состоянии TIME_WAIT, если это не повредит безопасности.
1 |
net.ipv4.tcp_tw_reuse = 1 |
Уменьшаем время пребывания сокета в состоянии FIN-WAIT-2
1 |
net.ipv4.tcp_fin_timeout = 30 |
Уменьшаем временной интервал попытки определения жизнеспособности соединения. По умолчанию 7200, т.е. через 2 часа после того как через соединение прошел последний пакет, система пошлет keep-alive запрос, чтобы узнать состояние соединения. Уменьшим этот параметр до 30 минут (1800 сек).
1 |
net.ipv4.tcp_keepalive_time = 1800 |
Уменьшим количество посылок keepalive запросов и интервалов между запросами. По умолчанию делается 9 попыток с интервалом в 75 секунд, что в свою очередь займет 9*75=675 сек (11,25 минут), что в сочетании с параметром по умолчанию net.ipv4.tcp_keepalive_time = 7200
(7200 сек = 2 часа) дает нам значение 2 часа 11,25 минут — минимальное значение времени после которого соединение будет закрыто нашей стороной после прохождения через это соединение последнего пакета. Это очень большой интервал.
Устанавливаем 7 попыток с интервалом в 30 секунд:
1 2 |
net.ipv4.tcp_keepalive_probes = 7 net.ipv4.tcp_keepalive_intvl = 30 |
Увеличиваем размеры буферов выделяемых под сетевые соединения.
1 2 3 4 5 6 |
net.core.wmem_max = 33554432 net.core.rmem_max = 33554432 net.core.rmem_default = 8388608 net.core.wmem_default = 4194394 net.ipv4.tcp_rmem = 4096 8388608 16777216 net.ipv4.tcp_wmem = 4096 4194394 16777216 |
Тут перечислены все параметры для удобства копирования в /etc/sysctl.conf
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Оптимизация работы сетевого стека ОС net.core.netdev_max_backlog=10000 net.core.somaxconn=262144 net.ipv4.tcp_syncookies=1 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_max_tw_buckets = 720000 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_timestamps = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1800 net.ipv4.tcp_keepalive_probes = 7 net.ipv4.tcp_keepalive_intvl = 30 net.core.wmem_max = 33554432 net.core.rmem_max = 33554432 net.core.rmem_default = 8388608 net.core.wmem_default = 4194394 net.ipv4.tcp_rmem = 4096 8388608 16777216 net.ipv4.tcp_wmem = 4096 4194394 16777216 |
Также Вам следует увеличить длину очереди для исходящих пакетов на каждом из сетевых интерфейсов. Делается это с помощью штатной команды ifconfig:
1 |
ifconfig eth0 txqueuelen 10000 |
или
1 |
ip link set eth0 txqueuelen 10000 |
Для сохранения значения очереди после перезагрузки внесети изменения в /etc/rc.local
до строчки exit 0
:
1 2 |
/sbin/ifconfig eth0 txqueuelen 10000 /sbin/ifconfig eth1 txqueuelen 10000 |
или, как менее предпочтительный вариант, внести изменения в файл /etc/network/interfaces
:
1 |
up ifconfig $IFACE txqueuelen 10000 |
Получить данные о работе сетевых интерфесов можно с помошью команд:
1 2 3 4 5 6 |
ethtool -S eth0 ifconfig (см. данные в полях txqueuelen:, RX packets, TX packets) netstat -s netstat -i cat /proc/net/dev cat /proc/net/netstat |
Более подробно о сетевых параметрах, которые вы можете менять через sysctl можно прочесть Ipsysctl tutorial 1.0.4. Перевод находится здесь. А также описание некоторых sysctl переменных ядра Linux и здесь.
[…] Another TCP: https://galaxydata.ru/community/optimizaciya-raboty-setevogo-steka-os-lin-61 […]