На производительность nginx очень большое влияние имеет настройка ОС.
В данной статье затронуты некоторые очень важные аспекты настройки ОС Linux, в частности Ubuntu 12.04 для достижения максимальной производительности сетевой подсистемы.
Внесите следующие изменения в /etc/sysctl.conf
, чтобы применить изменения выполните команду sysctl -p
.
Увеличим длину очереди для входящих пакетов. Значение 30000 это нормальное значение даже для 10GigE, если у Вас входящий канал не превышает 1Gbit/s, то выставлять значение переменной netdev_max_backlog более 10000 не имеет смысла.
net.core.netdev_max_backlog=10000
Сделать это можно внеся изменения в /etc/sysctl.conf
, как уже говорилось:
echo 'net.core.netdev_max_backlog = 10000' >> /etc/sysctl.conf
или на ходу:
sysctl –w net.core.netdev_max_backlog=10000
или так
echo 10000 > /proc/sys/net/core/netdev_max_backlog
Посмотреть текущее значение:
cat /proc/sys/net/core/netdev_max_backlog
Далее увеличиваем количество возможных подключений к сокету аналогичным образом. По умолчанию значение равно 128, что при высоко нагруженном сервере будет являться узким местом.
net.core.somaxconn=262144
Включаем tcp_syncookies, эта опция необходима для того, чтобы вы могли использовать параметрnet.ipv4.tcp_max_syn_backlog
описанный ниже.
net.ipv4.tcp_syncookies=1
Увеличиваем буфер под хранение SYN запросов на соединение. Значение по умолчанию 1024, что очень мало для нагруженных серверов.
net.ipv4.tcp_max_syn_backlog = 262144
Увеличим возможное количество сокетов в состоянии TIME_WAIT
net.ipv4.tcp_max_tw_buckets = 720000
Разрешаем быструю утилизацию сокетов находящихся в состоянии TIME_WAIT
net.ipv4.tcp_tw_recycle = 1
Включаем tcp_timestamps иначе не будет работать опция tcp_tw_reuse
описанная ниже
net.ipv4.tcp_timestamps = 1
Включаем механизм разрешающий использовать уже существующие сокеты, которые находятся в состоянии TIME_WAIT, если это не повредит безопасности.
net.ipv4.tcp_tw_reuse = 1
Уменьшаем время пребывания сокета в состоянии FIN-WAIT-2
net.ipv4.tcp_fin_timeout = 30
Уменьшаем временной интервал попытки определения жизнеспособности соединения. По умолчанию 7200, т.е. через 2 часа после того как через соединение прошел последний пакет, система пошлет keep-alive запрос, чтобы узнать состояние соединения. Уменьшим этот параметр до 30 минут (1800 сек).
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 секунд:
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
Тут перечислены все параметры для удобства копирования в /etc/sysctl.conf
:
# Оптимизация работы сетевого стека ОС 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:
ifconfig eth0 txqueuelen 10000
или
ip link set eth0 txqueuelen 10000
Для сохранения значения очереди после перезагрузки внесети изменения в /etc/rc.local
до строчки exit 0
:
/sbin/ifconfig eth0 txqueuelen 10000 /sbin/ifconfig eth1 txqueuelen 10000
или, как менее предпочтительный вариант, внести изменения в файл /etc/network/interfaces
:
up ifconfig $IFACE txqueuelen 10000
Получить данные о работе сетевых интерфесов можно с помошью команд:
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 и здесь.