Frage Müssen Sie den nginx-Durchsatz zu einem Upstream-Unix-Socket erhöhen - Linux-Kernel-Tuning?


Ich führe einen Nginx-Server, der als Proxy für einen Upstream-Unix-Socket fungiert, wie folgt:

upstream app_server {
        server unix:/tmp/app.sock fail_timeout=0;
}

server {
        listen ###.###.###.###;
        server_name whatever.server;
        root /web/root;

        try_files $uri @app;
        location @app {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Host $http_host;
                proxy_redirect off;
                proxy_pass http://app_server;
        }
}

Einige App-Server-Prozesse ziehen wiederum Anfragen ab /tmp/app.sock sobald sie verfügbar sind. Der hier verwendete App-Server ist Unicorn, aber ich glaube nicht, dass das für diese Frage relevant ist.

Das Problem ist, dass es scheint, dass nginx nach einer bestimmten Menge an Last keine Anfragen über den Socket mit einer ausreichend schnellen Rate erhalten kann. Es spielt keine Rolle, wie viele App-Server-Prozesse ich einstelle.

Ich bekomme eine Flut dieser Nachrichten im Nginx-Fehlerprotokoll:

connect() to unix:/tmp/app.sock failed (11: Resource temporarily unavailable) while connecting to upstream

Viele Anfragen führen zum Statuscode 502 und zu solchen, die nicht lange dauern. Der Nginx-Schreibwarteschlangenstatus liegt um 1000 herum.

Wie auch immer, ich habe das Gefühl, dass mir etwas offensichtlich fehlt, denn diese spezielle Konfiguration von nginx und app server ist ziemlich üblich, vor allem mit Unicorn (es ist die empfohlene Methode in der Tat). Gibt es irgendwelche Linux-Kernel-Optionen, die gesetzt werden müssen, oder etwas in nginx? Irgendwelche Ideen, wie man den Durchsatz zum Upstream-Socket erhöht? Etwas, was ich eindeutig falsch mache?

Zusätzliche Informationen zur Umgebung:

$ uname -a
Linux servername 2.6.35-32-server #67-Ubuntu SMP Mon Mar 5 21:13:25 UTC 2012 x86_64 GNU/Linux

$ ruby -v
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]

$ unicorn -v
unicorn v4.3.1

$ nginx -V
nginx version: nginx/1.2.1
built by gcc 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
TLS SNI support enabled

Aktuelle Kernel-Optimierungen:

net.core.rmem_default = 65536
net.core.wmem_default = 65536
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_mem = 16777216 16777216 16777216
net.ipv4.tcp_window_scaling = 1
net.ipv4.route.flush = 1
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.core.somaxconn = 8192
net.netfilter.nf_conntrack_max = 524288

Ulimit-Einstellungen für den nginx-Benutzer:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 20
file size               (blocks, -f) unlimited
pending signals                 (-i) 16382
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) unlimited
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

24
2018-06-14 22:46


Ursprung


Hast du die Ausgabe von überprüft? ulimit, insbesondere Anzahl der geöffneten Dateien? - Khaled
@Khaled, ulimit -n sagt 65535. - Ben Lee


Antworten:


Es hört sich an, als wäre der Flaschenhals die App, die den Socket antreibt und nicht Nginx selbst. Wir sehen das bei PHP mit Sockets im Vergleich zu einer TCP / IP-Verbindung. In unserem Fall würden PHP Engpässe viel früher als Nginx jemals passieren.

Haben Sie das Verbindungsverfolgungslimit sysctl.conf und das Socket-Backlog-Limit überprüft?

  • net.core.somaxconn
  • net.core.netdev_max_backlog

15
2018-06-20 20:05



Ich habe das Problem herausgefunden. Siehe die Antwort, die ich gepostet habe. Es tatsächlich war die App Engpässe, nicht die Steckdose, so wie du es postest. Ich hatte dies aufgrund einer Fehldiagnose früher ausgeschlossen, stellte aber fest, dass das Problem der Durchsatz auf einen anderen Server war. Ich habe das vor ein paar Stunden herausgefunden. Ich werde Ihnen die Prämie zusprechen, da Sie die Ursache des Problems trotz der falschen Diagnose, die ich in die Frage gestellt habe, ziemlich gut verstanden haben; Ich gebe jedoch das Häkchen zu meiner Antwort, weil meine Antwort die genauen Umstände beschreibt, so dass jemand in der Zukunft mit einem ähnlichen Problem helfen könnte. - Ben Lee
Einen neuen Server erhalten, der an einen Standort verschoben wurde, um einen angemessenen Durchsatz zu gewährleisten, das System vollständig neu zu erstellen und immer noch das gleiche Problem zu haben. So stellt sich heraus, dass mein Problem doch nicht gelöst ist ... = (Ich denke immer noch, es ist App-spezifisch, aber mir fällt nichts ein. Dieser neue Server ist genau wie ein anderer Server eingerichtet, wo es gut funktioniert. Ja, somacconn und netdev_max_backlog sind korrekt. - Ben Lee
Ihr Problem ist nicht nginx, es ist mehr als fähig - aber das heißt nicht, dass Sie keine Rogue-Einstellung haben. Steckdosen sind besonders empfindlich bei hoher Belastung, wenn die Grenzwerte nicht korrekt konfiguriert sind. Können Sie Ihre App stattdessen mit tcp / ip ausprobieren? - Ben Lessani - Sonassi
Gleiches Problem mit sogar noch schlimmerer Größe mit tcp / ip (Write Queue steigt noch schneller). Ich habe Nginx / Unicorn / Kernel alle genau so eingerichtet (soweit ich das beurteilen kann) auf einem anderen Computer, und dieses andere Gerät zeigt dieses Problem nicht. (Ich kann DNS zwischen den beiden Maschinen wechseln, um Live-Belastungstests zu erhalten, und habe DNS auf einem 60-sek-TTL) - Ben Lee
Der Durchsatz zwischen jeder Maschine und einer db-Maschine ist jetzt gleich, und die Latenzzeit zwischen der neuen Maschine und der db-Maschine ist ungefähr 30% höher als zwischen der alten Maschine und der db. Aber 30% mehr als ein Zehntel einer Millisekunde ist nicht das Problem. - Ben Lee


Du könntest versuchen, es anzuschauen unix_dgram_qlen, sehen proc Dokumente. Obwohl dies das Problem noch verschlimmern kann, indem es mehr in die Warteschlange zeigt? Du musst schauen (netstat -x ...)


2
2018-06-17 01:53



Irgendwelche Fortschritte damit? - jmw
Danke für die Idee, aber das schien keinen Unterschied zu machen. - Ben Lee


Ich habe das gelöst, indem ich die Rückstandsnummer in der config / unicorn.rb erhöht habe ... Ich hatte einen Backlog von 64.

 listen "/path/tmp/sockets/manager_rails.sock", backlog: 64

und ich bekam diesen Fehler:

 2014/11/11 15:24:09 [error] 12113#0: *400 connect() to unix:/path/tmp/sockets/manager_rails.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 192.168.101.39, server: , request: "GET /welcome HTTP/1.0", upstream: "http://unix:/path/tmp/sockets/manager_rails.sock:/welcome", host: "192.168.101.93:3000"

Jetzt bin ich auf 1024 gestiegen und bekomme den Fehler nicht:

 listen "/path/tmp/sockets/manager_rails.sock", backlog: 1024

0
2017-11-11 15:39





Backlog-Standardwert ist 1024 in Unicorn-Konfig.

http://unicorn.bogomips.org/Unicorn/Configurator.html

listen "/path/to/.unicorn.sock", :backlog => 1024

1024 Client ist Unix-Domain-Socket-Limit.


-1
2017-09-29 15:02