Délai d'expiration NGINX après +200 connexions simultanées

12

Ceci est mon nginx.conf(j'ai mis à jour la configuration pour m'assurer qu'il n'y a pas de PHP impliqué ou d'autres goulots d'étranglement):

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";
    }
}

J'utilise http://blitz.io/play pour tester mon serveur (j'ai acheté le plan de 10 000 connexions simultanées). Dans une course de 30 secondes, je reçois des 964coups sûrs et 5,587 timeouts. Le premier délai d'attente s'est produit à 40,77 secondes après le début du test lorsque le nombre d'utilisateurs simultanés était de 200.

Pendant le test, la charge du serveur était ( topsortie):

 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      

Ce n'est donc pas un problème de ressources serveur. Qu'est-ce que c'est alors?

MISE À JOUR 2011 12 09 GMT 17:36.

Jusqu'à présent, j'ai fait les changements suivants pour m'assurer que le goulot d'étranglement n'est pas TCP / IP. Ajouté à /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

Quelques informations de débogage supplémentaires:

[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 qui worker_rlimit_nofileest défini sur 10240nginx config.

MISE À JOUR 2011 12 09 GMT 19:02.

Il semble que plus je fais de changements, pire c'est, mais voici le nouveau fichier de configuration.

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;
}

MISE À JOUR 2011 12 11 GMT 20:11.

C'est la sortie de netstat -ntlapendant le test.

https://gist.github.com/d74750cceba4d08668ea

MISE À JOUR 2011 12 12 GMT 10:54.

Juste pour clarifier, le iptables(pare-feu) est désactivé pendant les tests.

MISE À JOUR 2011 12 12 GMT 22:47.

Ceci est le sysctl -p | grep memdépotoir.

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

MISE À JOUR 2011 12 12 GMT 22:49

J'utilise blitz.iopour exécuter tous les tests. L'URL que je teste est http://dev.anuary.com/test.txt , à l'aide de la commande suivante:--region ireland --pattern 200-250:30 -T 1000 http://dev.anuary.com/test.txt

MISE À JOUR 2011 12 13 GMT 13:33

nginxlimites utilisateur (définies /etc/security/limits.conf).

nginx       hard nofile 40000
nginx       soft nofile 40000
Guy
la source
Vous l'hébergez vous-même? Pas d'équilibreurs de charge ou quelque chose comme ça devant le serveur? Quelque chose du FAI qui pourrait le détecter comme une attaque DDoS et le ralentir?
Bart Silverstrim
Oui, c'est mon serveur. ovh.co.uk/dedicated_servers/eg_ssd.xml Rien qui pourrait ralentir l'attaque DDoS. J'ai également augmenté worker_processesà 4.
Gajus
Je viens de contacter OVH pour vérifier qu'il n'y a pas de titres de niveau réseau implémentés sur mon serveur. Non, il n'y en a pas.
Gajus
Quel type de données utilisez-vous à partir de cela? html, images, etc.?
pablo
1
Je pense que cela aiderait à exécuter un benchmark local pour exclure la configuration de nginx. N'est-ce pas?
3molo

Réponses:

2

Vous devrez vider vos connexions réseau pendant le test. Alors que le serveur peut avoir une charge presque nulle, votre pile TCP / IP peut être facturée. Recherchez les connexions TIME_WAIT dans une sortie netstat.

Si tel est le cas, vous souhaiterez vérifier les paramètres de réglage du noyau tcp / ip relatifs aux états d'attente TCP, au recylage TCP et à des mesures similaires.

De plus, vous n'avez pas décrit ce qui est testé.

Je teste toujours:

  • contenu statique (image ou fichier texte)
  • page php simple (phpinfo par exemple)
  • page d'application

Cela peut ne pas s'appliquer dans votre cas, mais c'est quelque chose que je fais lors des tests de performances. Tester différents types de fichiers peut vous aider à identifier le goulot d'étranglement.

Même avec du contenu statique, il est également important de tester différentes tailles de fichiers pour obtenir des délais d'expiration et d'autres mesures.

Nous avons des boîtes Nginx à contenu statique gérant plus de 3000 connexions actives. Donc, Nginx peut certainement le faire.

Mise à jour: votre netstat affiche de nombreuses connexions ouvertes. Vous voudrez peut-être essayer de régler votre pile TCP / IP. De plus, quel fichier demandez-vous? Nginx devrait fermer rapidement le port.

Voici une suggestion pour 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

Ces valeurs sont très faibles, mais j'ai eu du succès avec elles sur des boîtes Nginx à concurrence élevée.

jeffatrackaid
la source
Voir leUPDATE 2011 12 09 GMT 17:36.
Gajus
ajouté mis à jour à la réponse principale en raison du code.
jeffatrackaid
veuillez ajouter la sortie supérieure complète pendant le test, vous ne devez pas vérifier uniquement la quantité de CPU utilisée par nginx.
Giovanni Toraldo
1
soyez prudent lorsque vous utilisez net.ipv4.tcp_tw_recycle = 1, de manière générale: pas une bonne idée. la réutilisation est ok tho.
anonyme-un
Pourquoi ne pas utiliser le socket Linux au lieu de localhost?
BigSack
1

Encore une autre hypothèse. Vous avez augmenté worker_rlimit_nofile, mais le nombre maximal de clients est défini dans la documentation comme

max_clients = worker_processes * worker_connections

Et si vous essayez de passer worker_connectionsà 8192, par exemple? Ou, s'il y a suffisamment de cœurs CPU, augmenter worker_processes?

minaev
la source
1

J'avais un problème très similaire avec une boîte nginx servant d'équilibreur de charge avec un amont des serveurs apache.

Dans mon cas, j'ai pu isoler le problème lié au réseau car les serveurs Apache en amont étaient surchargés. Je pouvais le recréer avec de simples scripts bash pendant que le système global était sous charge. Selon une strace de l'un des processus bloqués, l'appel de connexion obtenait un ETIMEDOUT.

Ces paramètres (sur les serveurs nginx et en amont) ont éliminé le problème pour moi. J'obtenais 1 ou 2 timeouts par minute avant de faire ces changements (boîtes gérant ~ 100 demandes / s) et j'obtiens maintenant 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

Je ne recommanderais pas d'utiliser net.ipv4.tcp_tw_recycle ou net.ipv4.tcp_tw_reuse, mais si vous voulez en utiliser un, allez avec ce dernier. Ils peuvent causer des problèmes bizarres en cas de latence et si celle-ci est au moins la plus sûre des deux.

Je pense qu'avoir tcp_fin_timeout réglé sur 1 ci-dessus peut également causer des problèmes. Essayez de le mettre à 20/30 - toujours bien en dessous de la valeur par défaut.

gtuhl
la source
0

n'est peut-être pas un problème nginx, pendant que vous testez sur blitz.io, faites:

tail -f /var/log/php5-fpm.log

(c'est ce que j'utilise pour gérer le php)

cela déclenche une erreur et les délais d'attente commencent à augmenter:

WARNING: [pool www] server reached pm.max_children setting (5), consider raising it

alors, mettez plus max_children sur fmp conf et c'est fait! ;RÉ

jipipayo
la source
Le problème est le même si je l'ai return 200 "test"dans NGINX. Cela signifie que NGINX ne va même pas jusqu'à appeler PHP-FPM.
Gajus
0

Vous avez trop bas max open files(1024), essayez de changer et redémarrez nginx. ( cat /proc/<nginx>/limitspour confirmer)

ulimit -n 10240

Et worker_connectionspassez à 10240 ou plus.

utilisateur3368344
la source
Je ne sais pas pourquoi cela a été rejeté. Cela me semble être la bonne réponse.
Ryan Angilly