Тайм-аут NGINX после +200 одновременных соединений

12

Это мое 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
Гай
источник
Вы сами принимаете это? Нет балансировщиков нагрузки или чего-то подобного перед сервером? Что-то от интернет-провайдера, которое может обнаружить его как DDoS-атаку и снизить его?
Барт Сильверстрим
Да, это мой сервер. ovh.co.uk/dedicated_servers/eg_ssd.xml Ничего, что могло бы ослабить DDoS-атаку. Я также увеличился worker_processesдо 4.
Gajus
Просто связался с OVH, чтобы проверить, нет ли на моем сервере ценных бумаг сетевого уровня. Нет, нет.
Gajus
какие данные вы обслуживаете из этого? HTML, изображения и т. д.?
Пабло
1
Я думаю, что это поможет запустить локальный тест для исключения конфигурации nginx. Не так ли?
3моло

Ответы:

2

Вам нужно будет сбросить сетевые подключения во время теста. В то время как сервер может иметь почти нулевую нагрузку, ваш стек 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 с высоким параллелизмом.

jeffatrackaid
источник
СмотритеUPDATE 2011 12 09 GMT 17:36.
Gajus
добавлено обновление к основному ответу из-за кода.
Jeffatrackaid
пожалуйста, добавьте полный верхний вывод во время теста, вы не должны проверять только то, сколько использует процессор nginx.
Джованни Торальдо
1
будьте осторожны при использовании net.ipv4.tcp_tw_recycle = 1, вообще говоря: не очень хорошая идея. повторное использование в порядке, хотя.
анонимный -
Почему бы не использовать Linux-сокет вместо localhost?
BigSack
1

Еще одна гипотеза. Вы увеличили worker_rlimit_nofile, но максимальное количество клиентов определяется в документации как

max_clients = worker_processes * worker_connections

Что если вы попытаетесь поднять ставку worker_connectionsдо 8192? Или, если достаточно процессорных ядер, увеличить worker_processes?

Минаев
источник
1

У меня была очень похожая проблема с боксом 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 - все еще намного ниже значения по умолчанию.

gtuhl
источник
0

возможно, это не проблема 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

оборота джипипайо
источник
Проблема такая же, если у меня есть return 200 "test"в NGINX. Это означает, что NGINX даже не доходит до вызова PHP-FPM.
Gajus
0

У вас слишком мало max open files(1024), попробуйте изменить и перезапустить nginx. ( cat /proc/<nginx>/limitsподтвердить)

ulimit -n 10240

И увеличить worker_connectionsдо 10240 или выше.

user3368344
источник
Я не уверен, почему за это проголосовали. Похоже, правильный ответ для меня.
Райан Ангилли