Тайм-аут NGINX после +200 одновременных соединений
Это мое nginx.conf
(Я обновил конфигурацию, чтобы убедиться, что PHP не задействован или какие-либо другие узкие места):
user nginx;
worker_processes 4;
worker_rlimit_nofile 10240;
pid /var/run/nginx.pid;
events
{
worker_connections 1024;
}
http
{
include /etc/nginx/mime.types;
error_log /var/www/log/nginx_errors.log warn;
port_in_redirect off;
server_tokens off;
sendfile on;
gzip on;
client_max_body_size 200M;
map $scheme $php_https { default off; https on; }
index index.php;
client_body_timeout 60;
client_header_timeout 60;
keepalive_timeout 60 60;
send_timeout 60;
server
{
server_name dev.anuary.com;
root "/var/www/virtualhosts/dev.anuary.com";
}
}
Я использую http://blitz.io/play для тестирования моего сервера (я купил план 10 000 одновременных подключений). Через 30 секунд я получаю 964
хиты и 5,587 timeouts
, Первый тайм-аут произошел через 40,77 секунды после теста, когда число одновременных пользователей составило 200.
Во время теста нагрузка на сервер была (top
выход):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 20225 nginx 20 0 48140 6248 1672 S 16.0 0.0 0:21.68 nginx
1 root 20 0 19112 1444 1180 S 0.0 0.0 0:02.37 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT 0 0 0 0 S 0.0 0.0 0:00.03 migration/0
Поэтому это не проблема ресурсов сервера. Что тогда?
ОБНОВЛЕНИЕ 2011 12 09 GMT 17:36.
До сих пор я делал следующие изменения, чтобы убедиться, что узким местом не является TCP/IP. Добавлено в /etc/sysctl.conf
:
# These ensure that TIME_WAIT ports either get reused or closed fast.
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_tw_recycle = 1
# TCP memory
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
Еще немного отладочной информации:
[root@server node]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 126767
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
NB Это worker_rlimit_nofile
установлен в 10240
Конфигурация nginx
ОБНОВЛЕНИЕ 2011 12 09 GMT 19:02.
Похоже, чем больше изменений я делаю, тем хуже становится, но здесь новый файл конфигурации.
user nginx;
worker_processes 4;
worker_rlimit_nofile 10240;
pid /var/run/nginx.pid;
events
{
worker_connections 2048;
#1,353 hits, 2,751 timeouts, 72 errors - Bummer. Try again?
#1,408 hits, 2,727 timeouts - Maybe you should increase the timeout?
}
http
{
include /etc/nginx/mime.types;
error_log /var/www/log/nginx_errors.log warn;
# http://blog.martinfjordvald.com/2011/04/optimizing-nginx-for-high-traffic-loads/
access_log off;
open_file_cache max=1000;
open_file_cache_valid 30s;
client_body_buffer_size 10M;
client_max_body_size 200M;
proxy_buffers 256 4k;
fastcgi_buffers 256 4k;
keepalive_timeout 15 15;
client_body_timeout 60;
client_header_timeout 60;
send_timeout 60;
port_in_redirect off;
server_tokens off;
sendfile on;
gzip on;
gzip_buffers 256 4k;
gzip_comp_level 5;
gzip_disable "msie6";
map $scheme $php_https { default off; https on; }
index index.php;
server
{
server_name ~^www\.(?P<domain>.+);
rewrite ^ $scheme://$domain$request_uri? permanent;
}
include /etc/nginx/conf.d/virtual.conf;
}
ОБНОВЛЕНИЕ 2011 12 11 GMT 20:11.
Это вывод netstat -ntla
во время теста.
https://gist.github.com/d74750cceba4d08668ea
ОБНОВЛЕНИЕ 2011 12 12 GMT 10:54.
Просто чтобы уточнить, iptables
(брандмауэр) отключен во время тестирования.
ОБНОВЛЕНИЕ 2011 12 12 GMT 22:47.
Это sysctl -p | grep mem
свалка.
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 8388608 8388608 8388608
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 65536 8388608
net.ipv4.route.flush = 1
net.ipv4.ip_local_port_range = 1024 65000
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
net.core.wmem_max = 8388608
net.core.wmem_default = 65536
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 4096
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
ОБНОВЛЕНИЕ 2011 12 12 GMT 22:49
я использую blitz.io
запустить все тесты. URL, который я тестирую, это http://dev.anuary.com/test.txt, используя следующую команду: --region ireland --pattern 200-250:30 -T 1000 http://dev.anuary.com/test.txt
ОБНОВЛЕНИЕ 2011 12 13 GMT 13:33
nginx
пользовательские ограничения (устанавливаются в /etc/security/limits.conf
).
nginx hard nofile 40000
nginx soft nofile 40000
5 ответов
Вам нужно будет сбросить сетевые подключения во время теста. В то время как сервер может иметь почти нулевую нагрузку, ваш стек TCP/IP может быть платным. Ищите соединения TIME_WAIT в выводе netstat.
Если это так, то вам нужно проверить параметры ядра tcp/ip, относящиеся к состояниям ожидания TCP, повторному использованию TCP и другим подобным показателям.
Также вы не описали, что тестируется.
Я всегда проверяю:
- статический контент (изображение или текстовый файл)
- простая страница php (например, phpinfo)
- страница приложения
Это может не применяться в вашем случае, но это то, что я делаю при тестировании производительности. Тестирование различных типов файлов может помочь вам определить узкие места.
Даже со статическим контентом, тестирование файлов разного размера также важно, чтобы определить время ожидания и другие показатели.
У нас есть несколько статических блоков Nginx, обрабатывающих более 3000 активных соединений. Так что Nginx, безусловно, может это сделать.
Обновление: ваш netstat показывает много открытых соединений. Возможно, стоит попробовать настроить ваш стек TCP/IP. Кроме того, какой файл вы запрашиваете? Nginx должен быстро закрыть порт.
Вот предложение для sysctl.conf:
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
Эти значения очень низкие, но у меня был успех с ними на блоках Nginx с высоким параллелизмом.
У меня была очень похожая проблема с боксом nginx, служащим балансировщиком нагрузки с вышестоящими серверами Apache.
В моем случае я смог изолировать проблему, связанную с сетью, поскольку вышестоящие серверы Apache стали перегруженными. Я мог бы воссоздать его с помощью простых скриптов bash, пока вся система была загружена. По словам одного из зависших процессов, вызов connect получал ETIMEDOUT.
Эти настройки (на nginx и вышестоящих серверах) устранили проблему для меня. Я получал 1 или 2 тайм-аута в минуту, прежде чем вносить эти изменения (блоки обрабатывают ~100 запросов / с), и теперь получаю 0.
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 20
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 4096
net.ipv4.tcp_max_tw_buckets = 400000
net.core.somaxconn = 4096
Я бы не рекомендовал использовать net.ipv4.tcp_tw_recycle или net.ipv4.tcp_tw_reuse, но если вы хотите использовать один, используйте последний. Они могут вызвать причудливые проблемы, если вообще есть какое-либо время ожидания, и последнее, по крайней мере, безопаснее из двух.
Я думаю, что tcp_fin_timeout, установленный в 1 выше, может также вызвать некоторые проблемы. Попробуйте установить его на 20/30 - все еще намного ниже значения по умолчанию.
Еще одна гипотеза. Вы увеличили worker_rlimit_nofile
, но максимальное количество клиентов определяется в документации как
max_clients = worker_processes * worker_connections
Что делать, если вы попытаетесь поднять worker_connections
к 8192? Или, если процессорных ядер достаточно, увеличьте worker_processes
?
Возможно , это не проблема nginx, пока вы тестируете на blitz.io:
tail -f /var/log/php5-fpm.log
(вот что я использую для обработки PHP)
это вызывает ошибку, и таймауты начинают увеличиваться:
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
Итак, поместите больше max_children в fmp conf и все готово!;D
У тебя слишком низкий max open files
(1024), попробуйте изменить и перезапустить nginx. (cat /proc/<nginx>/limits
подтвердить)
ulimit -n 10240
И увеличить worker_connections
до 10240 или выше.