NGINX-Timeout nach +200 gleichzeitigen Verbindungen


12

Dies ist meine nginx.conf(ich habe die Konfiguration aktualisiert, um sicherzustellen, dass kein PHP beteiligt ist oder andere Engpässe vorliegen):

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

Ich benutze http://blitz.io/play , um meinen Server zu testen (ich habe den 10 000 Concurrent Connections Plan gekauft). In 30 Sekunden bekomme ich 964Hits und 5,587 timeouts. Die erste Zeitüberschreitung trat nach 40,77 Sekunden im Test auf, als die Anzahl der gleichzeitigen Benutzer bei 200 lag.

Während des Tests wurde die Serverlast ( topAusgabe):

 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      

Daher handelt es sich nicht um ein Problem mit Serverressourcen. Was ist es dann?

UPDATE 2011 12 09 GMT 17:36.

Bisher habe ich die folgenden Änderungen vorgenommen, um sicherzustellen, dass der Engpass nicht TCP / IP ist. Hinzugefügt zu/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

Einige weitere Debug-Informationen:

[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 das worker_rlimit_nofile ist auf 10240nginx config gesetzt.

UPDATE 2011 12 09 GMT 19:02.

Es sieht so aus, als ob je mehr Änderungen ich mache, desto schlimmer wird es, aber hier die neue Konfigurationsdatei.

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

UPDATE 2011 12 11 GMT 20:11.

Dies ist die Ausgabe von netstat -ntla während des Tests .

https://gist.github.com/d74750cceba4d08668ea

UPDATE 2011 12 12 GMT 10:54.

Zur Verdeutlichung ist die iptables(Firewall) beim Testen ausgeschaltet.

UPDATE 2011 12 12 GMT 22:47.

Das ist die sysctl -p | grep memMüllkippe.

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

UPDATE 2011 12 12 GMT 22:49

Ich benutze blitz.io, um alle Tests auszuführen. Die URL, die ich teste, lautet http://dev.anuary.com/test.txt und verwendet den folgenden Befehl:--region ireland --pattern 200-250:30 -T 1000 http://dev.anuary.com/test.txt

UPDATE 2011 12 13 GMT 13:33

nginxBenutzergrenzen (eingestellt in /etc/security/limits.conf).

nginx       hard nofile 40000
nginx       soft nofile 40000

Sie hosten das selbst? Keine Load Balancer oder ähnliches vor dem Server? Etwas vom ISP, das es möglicherweise als DDoS-Angriff erkennt und herunterfährt?
Bart Silverstrim

Ja, das ist mein Server. ovh.co.uk/dedicated_servers/eg_ssd.xml Nichts, was DDoS-Angriffe beeinträchtigen würde. Ich habe auch erhöht worker_processeszu 4.
Gajus

Wenden Sie sich einfach an OVH, um zu überprüfen, ob auf meinem Server Sicherheiten auf Netzwerkebene implementiert sind. Nein, gibt es nicht.
Gajus

Welche Art von Daten liefern Sie daraus? HTML, Bilder, etc?
Pablo

1
Ich denke, es würde helfen, einen lokalen Benchmark durchzuführen, um die Nginx-Konfiguration auszuschließen. Nicht wahr
15.

Antworten:


2

Sie müssen Ihre Netzwerkverbindungen während des Tests sichern. Während der Server möglicherweise fast leer ist, wird Ihr TCP / IP-Stack möglicherweise abgerechnet. Suchen Sie in einer netstat-Ausgabe nach TIME_WAIT-Verbindungen.

Wenn dies der Fall ist, sollten Sie die Optimierung von TCP / IP-Kernelparametern in Bezug auf TCP-Wartezustände, TCP-Recyling und ähnliche Metriken überprüfen.

Außerdem haben Sie nicht beschrieben, was getestet wird.

Ich teste immer:

  • statischer Inhalt (Bild- oder Textdatei)
  • einfache PHP Seite (zB phpinfo)
  • Anwendungsseite

Dies mag in Ihrem Fall nicht zutreffen, aber ich mache es, wenn ich Leistungstests durchführe. Das Testen verschiedener Dateitypen kann Ihnen dabei helfen, den Engpass zu lokalisieren.

Auch bei statischen Inhalten ist es wichtig, verschiedene Dateigrößen zu testen, um Timeouts und andere Messdaten zu erhalten.

Wir haben statische Inhalte für Nginx-Boxen, die über 3000 aktive Verbindungen verwalten. Nginx kann es also mit Sicherheit.

Update: Ihr netstat zeigt viele offene Verbindungen. Möglicherweise möchten Sie versuchen, Ihren TCP / IP-Stack zu optimieren. Welche Datei fordern Sie an? Nginx sollte den Port schnell schließen.

Hier ist ein Vorschlag für 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

Diese Werte sind sehr niedrig, aber ich hatte Erfolg mit ihnen auf Nginx-Boxen mit hoher Parallelität.


Siehe dieUPDATE 2011 12 09 GMT 17:36.
Gajus

hinzugefügt, um die Hauptantwort aufgrund des Codes zu aktualisieren.
Jeffatrackaid

Bitte addieren Sie die gesamte Top-Ausgabe während des Tests. Sie sollten nicht nur überprüfen, wie viel CPU-Nginx verwendet.
Giovanni Toraldo

1
Seien Sie vorsichtig, wenn Sie net.ipv4.tcp_tw_recycle = 1 verwenden, im Allgemeinen: keine gute Idee. Wiederverwendung ist ok tho.
anonym-ein

Warum nicht Linux Socket anstelle von localhost verwenden?
BigSack

1

Noch eine Hypothese. Sie haben zugenommen worker_rlimit_nofile, aber die maximale Anzahl der Clients ist in der Dokumentation als definiert

max_clients = worker_processes * worker_connections

Was ist, wenn Sie versuchen, worker_connectionsauf 8192 zu erhöhen ? Oder, wenn es genügend CPU-Kerne gibt, erhöhen Sie worker_processes?


1

Ich hatte ein sehr ähnliches Problem mit einer Nginx-Box, die als Load Balancer bei einem Upstream von Apache-Servern dient.

In meinem Fall konnte ich das Problem als Netzwerkproblem eingrenzen, da die vorgelagerten Apache-Server überlastet waren. Ich konnte es mit einfachen Bash-Skripten erstellen, während das Gesamtsystem geladen war. Laut einer Reihe von Prozessen, die hängengeblieben sind, hat der Connect-Aufruf ein ETIMEDOUT erhalten.

Diese Einstellungen (auf den Nginx- und Upstream-Servern) haben das Problem für mich beseitigt. Ich habe 1 oder 2 Timeouts pro Minute erhalten, bevor ich diese Änderungen vorgenommen habe (Boxen, die ~ 100 Reqs / s verarbeiten) und jetzt 0 erhalten.

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

Ich würde nicht empfehlen, net.ipv4.tcp_tw_recycle oder net.ipv4.tcp_tw_reuse zu verwenden, aber wenn Sie eine verwenden möchten, gehen Sie mit letzterer. Sie können bizarre Probleme verursachen, wenn es überhaupt eine Latenz gibt und letztere mindestens die sicherere von beiden ist.

Ich denke, dass das Setzen von tcp_fin_timeout auf 1 ebenfalls Probleme verursachen kann. Versuchen Sie es mit 20/30 - immer noch weit unter der Standardeinstellung.


0

vielleicht ist nginx kein problem, während du auf blitz.io testest mache ein:

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

(das ist, was ich benutze, um die PHP zu behandeln)

Dies löst einen Fehler aus und die Zeitüberschreitung beginnt zu steigen:

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

Also, setze mehr max_children auf fmp conf und fertig! ; D


Das Problem ist das gleiche, wenn ich return 200 "test"in NGINX habe. Dies bedeutet, dass NGINX nicht einmal so weit geht, PHP-FPM aufzurufen.
Gajus

0

Sie haben zu wenig max open files(1024), versuchen Sie, nginx zu ändern und neu zu starten. ( cat /proc/<nginx>/limitszur Bestätigung)

ulimit -n 10240

Und worker_connectionsauf 10240 oder höher erhöhen .


Ich bin nicht sicher, warum dies abgelehnt wurde. Klingt nach der richtigen Antwort für mich.
Ryan Angilly
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.