Задача: затюнить размеры сокетов у Nginx, чтобы без потерь переживать всплески трафика.
Уточним размер буфера чтения:
# ss -ntlmO | grep ':80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb131072,t0,tb16384,f0,w0,o0,bl0,d0)
Нас интересует значение
rb - 131072 байт. Окей, допустим мы хотим сделать его равным 6291456 байт (~6мб).
В Nginx за размер буфер приема отвечает параметр
rcvbuf, см. док .Вносим изменения в конфиг и перезапускаем Nginx:
# grep listen /etc/nginx/nginx.conf
listen 80 rcvbuf=6291456;
# systemctl restart nginx
Проверяем:
# ss -ntlmO | grep ':80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb425984,t0,tb16384,f0,w0,o0,bl0,d0)
425984 не похоже на 6291456 ;)———
# sysctl -a | grep rmem
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.ipv4.tcp_rmem = 4096 131072 18874368
...
Среднее значение
tcp_rmem соответствует размеру буфера до изменений, а новое (425984) не совпадает ни с чем.Документация к
rcvbuf говорит, что настройка соответствует опции сокета SO_RCVBUF:# man 7 socket
SO_RCVBUF
Sets or gets the maximum socket receive buffer in bytes. The kernel doubles this value (to allow space for bookkeeping overhead) when it is set using setsockopt(2), and this doubled value is returned by getsockopt(2). The default value is set by the /proc/sys/net/core/rmem_default file, and the maximum allowed value is set by the /proc/sys/net/core/rmem_max file...
1. ядро будет удваивать переданное значение (что и увидим в`rb`)
2. дефолтное (начальное) равно
rmem_default;3. максимум задается через
rmem_max.Причины удвоения (хотя там могут быть разные варианты) стоит искать в "man 7 tcp" и в "net.ipv4.tcp_adv_win_scale". Или в подробной статье от CloudFlare.
Окей, произведем расчеты:
425984 / 2 = 212992.Похоже, что мы уперлись в
net.core.rmem_max:# sysctl net.core.rmem_max=6291456
net.core.rmem_max = 6291456
# nginx -s reload
# ss -ntlmO | grep '0.0.0.0:80 '
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* skmem:(r0,rb12582912,t0,tb16384,f0,w0,o0,bl0,d0)
Получаем искомое
rb в 12582912 (6mb * 2). Промежуточный итог: если мы выставляем руками размеры буферов на уровне приложение (опция
SO_RCVBUF), следует учесть это и в net.core.rmem_max.Следующая часть.
tags: #tcp #linux #kernel