Час очікування 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

Примітка. worker_rlimit_nofileНалаштування 10240nginx config.

ОНОВЛЕННЯ 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. Чи не так?
3molo

Відповіді:


2

Вам потрібно буде скинути мережеві з'єднання під час тесту. Хоча сервер може мати майже нульове навантаження, ваш TCP / IP стек може бути виставлений рахунок. Шукайте TIME_WAIT-з'єднання у виході netstat.

У такому випадку вам потрібно перевірити налаштування параметрів ядра tcp / ip, що стосуються станів TCP Wait, переробки 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.


Дивіться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.

У моєму випадку мені вдалося виокремити проблему, пов’язану з мережею, оскільки сервери апаш-верху за течією перевантажувалися. Я міг відтворити це за допомогою простих скриптів bash, поки загальна система була під навантаженням. Відповідно до напруженості одного із завислих процесів, виклик з'єднання отримував ETIMEDOUT.

Ці налаштування (на серверах nginx та upstream) усунули проблему для мене. Я отримував 1 або 2 тайм-аути в хвилину, перш ніж вносити ці зміни (обробка ящиків ~ 100 reqs / s) і тепер отримую 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 - все ще далеко за замовчуванням.


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.
Гаджус

0

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

ulimit -n 10240

І збільшити worker_connectionsдо 10240 або вище.


Я не впевнений, чому це було проголосовано. Мені звучить правильна відповідь.
Райан Ангілі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.