Fehlerhafte Gateway-Fehler beim Laden von nginx + Unicorn (Rails 3 app)

7

Ich habe eine Rails (3.2) -App, die auf Nginx und Unicorn auf einer Cloud-Plattform läuft. Die "Box" läuft auf Ubuntu 12.04.

Wenn die Systemauslastung bei ca. 70% oder mehr liegt, startet nginx abrupt (und scheinbar zufällig) und gibt 502 Bad gateway errors aus ; Wenn die Ladung weniger ist, gibt es nichts Vergleichbares. Ich habe mit verschiedenen Kernen experimentiert (4, 6, 10 - ich kann "Hardware ändern", wie es auf der Cloud-Plattform ist), und die Situation ist immer die gleiche. (Die CPU-Belastung ist ähnlich der Systemlast, das Benutzerland ist 55%, der Rest ist System und gestohlen, mit viel freiem Speicher, kein Swapping.)

502 kommen normalerweise in Stapeln, aber nicht immer.

(Ich betreibe einen Einhorn-Arbeiter pro Kern und einen oder zwei nginx-Arbeiter. Siehe die relevanten Teile der unten stehenden Konfigurationen, wenn sie auf 10 Kernen laufen.)

Ich weiß nicht wirklich, wie ich die Ursache dieser Fehler verfolgen soll. Ich vermute, dass es etwas damit zu tun hat, dass Einhornarbeiter nicht (rechtzeitig) dienen können, aber es sieht merkwürdig aus, weil sie die CPU nicht zu sättigen scheinen und ich keinen Grund sehe, warum sie auf IO warten würden (aber ich tue es nicht Ich weiß auch nicht, wie ich das sicherstellen kann.

Können Sie mir bitte helfen, wie ich die Ursache finden kann?

Unicorn-Konfiguration ( unicorn.rb ):

%Vor%

Und die ngnix config:

/etc/nginx/nginx.conf :

%Vor%

/etc/nginx/conf.d/app.conf :

%Vor%     
fastcatch 18.03.2013, 13:14
quelle

1 Antwort

21

Nach dem googlen nach Ausdrücken, die im nginx-Fehlerprotokoll gefunden wurden, stellte sich heraus, dass es ein bekanntes Problem ist, das nichts mit nginx zu tun hat, wenig mit Einhorn zu tun hat und in OS (linux) -Einstellungen verankert ist.

Der Kern des Problems besteht darin, dass der Socket-Backlog zu kurz ist. Es gibt verschiedene Überlegungen, wie viel dies sein sollte (ob Sie einen Cluster-Member-Fehler ASAP so schnell wie möglich erkennen oder die Anwendung die Lastgrenzen überschreiten lassen wollen). Aber in jedem Fall muss die listen :backlog optimiert werden.

Ich fand, dass in meinem Fall ein listen ... :backlog => 2048 ausreichend war. (Ich habe nicht viel experimentiert, obwohl es einen guten Hack gibt, wenn du magst, zwei Sockets für die Kommunikation zwischen Nginx und Einhorn mit verschiedenen Rückständen und länger Backup; dann schau im Nginx-Log, wie oft die kürzere Queue ausfällt .) Bitte beachten Sie, dass es nicht das Ergebnis einer wissenschaftlichen Berechnung und YMMV ist.

Beachten Sie jedoch, dass die meisten OS-es (die meisten Linux-Distributionen, einschließlich Ubuntu 12.04) wesentlich niedrigere Standard-Limits für Socket-Backlog-Größen (so niedrig wie 128) haben.

Sie können die Betriebssystemgrenzen wie folgt ändern (als root):

%Vor%

Fügen Sie diese zu /etc/sysctl.conf hinzu, um die Änderungen dauerhaft zu machen. ( /etc/sysctl.conf kann ohne Neustart mit sysctl -p neu geladen werden.)

Es gibt Hinweise darauf, dass Sie möglicherweise die maximale Anzahl von Dateien erhöhen müssen, die auch von einem Prozess geöffnet werden können (verwenden Sie ulimit -n und /etc/security/limits.conf für Permanenz). Ich hatte das schon aus anderen Gründen getan, deshalb kann ich nicht sagen, ob es einen Unterschied macht oder nicht.

    
fastcatch 21.03.2013, 09:56
quelle

Tags und Links