nginx - Load Balancer - Beträchtliche Verzögerung, wenn der Upstream-Knoten offline / inaktiv ist


7

Ausführen von nginx 1.0.15 unter CentOS 6.5 . Ich habe drei Upstream-Server und alles funktioniert einwandfrei. Wenn ich jedoch einen Ausfall simuliere und einen der Upstream-Server herunterfahre, stelle ich eine erhebliche Verzögerung der Antwortzeiten fest (zusätzliche 5-7 Sekunden). Sobald ich den ausgefallenen Server wieder online schalte, verschwindet die Verzögerung. Außerdem ist mir aufgefallen, dass die Antwortzeiten normal sind, wenn ich den httpd-Dienst auf dem simulierten Ausfallserver einfach stoppe. Die Verzögerung tritt nur auf, wenn der Server vollständig ausgefallen ist.

Hier ist mein conf:

upstream prod_example_com {

    server app-a-1:51000;

    server app-a-2:51000;

    server app-a-3:51000;

}


server {

    # link:  http://wiki.nginx.org/MailCoreModule#server_name
    server_name example.com www.example.com *.example.com;

    #-----
    # Upstream logic
    #-----


    set $upstream_type prod_example_com;


    #-----

    include include.d/common.conf;

    # Configure logging
    access_log  /var/log/nginx/example/access/access.log access;
    error_log   /var/log/nginx/example/error.log error;

    location / {

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_pass
        proxy_pass  http://$upstream_type$request_uri;

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_set_header
        proxy_set_header    Host    $host;
        proxy_set_header    X-Real-IP   $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_pass
        proxy_pass  http://$upstream_type$request_uri;

        # link: http://wiki.nginx.org/HttpProxyModule#proxy_set_header
        proxy_set_header    Host    $host;
        proxy_set_header    X-Real-IP   $remote_addr;
        proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;

        proxy_hide_header expires;
        proxy_hide_header Cache-Control

         # Even tho this reads like the older syntax, it is handled internally by nginx to set max age to now + 1 year
         expires max;

        # Allow intermediary caches the ability to cache the asset
        add_header Cache-Control "public";
    }
}

Ich habe die Vorschläge für ähnliche Beiträge wie diesen ausprobiert . Und anscheinend ist meine Version von Nginx zu alt, um health_checks zu unterstützen, wie in den Nginx- Dokumenten beschrieben . Ich habe auch versucht, die max_fails=2und fail_timeout=120für die app-a-3Upstream-Definition explizit festzulegen, aber keine davon scheint die zusätzliche Verzögerung von 5 bis 7 Sekunden für jede Anforderung zu vermeiden, wenn sie app-a-3offline ist.

- Update -

Pro Anfrage ist hier die Ausgabe für eine einzelne Anfrage, wenn diese app-a-3vollständig ausgefallen ist. Das einzige, was ich ungewöhnlich sehen konnte, ist die Verzögerung von 3 Sekunden zwischen dem ersten Ereignis und dem nachfolgenden Ereignis.

- Update Nr. 2 -

Es sieht so aus, als hätte Nginx vor einigen Jahren beschlossen, Nginx Plus zu entwickeln, das aktive Gesundheitschecks hinzufügt, jedoch für einen jährlichen Supportvertrag. Aufgrund einiger Artikel, die ich gelesen habe, hatte Nginx es satt, Unternehmen Millionen zu machen und nichts dafür zu bekommen.

Wie in den Kommentaren erwähnt, booten wir und haben nicht das Geld, um einen Vertrag über 1.350 Dollar abzuschließen. Ich habe dieses Repo gefunden , das die Funktionalität bietet. Sie fragen sich, ob jemand Erfahrung damit hat? Stabil? Performant?

Im schlimmsten Fall muss ich nur die Kugel beißen und die zusätzlichen 20 US-Dollar pro Monat für einen Linode "Node Balancer" bezahlen, von dem ich mir ziemlich sicher bin, dass er auf Nginx Plus basiert. Das einzige Problem besteht darin, dass außer einigen generischen Optionen keine Kontrolle über die Konfiguration besteht. Daher können mehrere vhost-Dateien nicht über einen Balancer unterstützt werden, und alle Knoten müssen sich im selben Datencenter befinden.

- Update Nr. 3 -

Hier sind einige Belagerungsergebnisse . Es scheint, dass der zweite Knoten falsch konfiguriert ist, da er nur etwa 75% der Anforderungen verarbeiten kann, die der erste und der dritte Knoten bearbeiten. Außerdem fand ich es seltsam, dass die Leistung beim Abschalten des zweiten Knotens so schlecht war, als ob ich den dritten Knoten (mit besserer Leistung) offline geschaltet hätte. Die Logik würde vorschreiben, dass ich beim Entfernen des schwachen Glieds (zweiter Knoten) eine bessere Leistung erzielen würde, da die verbleibenden zwei Knoten einzeln eine bessere Leistung als das schwache Glied erzielen.

Zusamenfassend:

node 1, 2, 3 + my nginx = 2037 requests

node 1, 2 + my nginx  = 733 requests

node 1, 3 + my nginx = 639 requests (huh? these two perform better individually so together should be somewhere around ~1500 requests, based on 2000 requests when all nodes are up)

node 1, 3 + Linode Load Balancer = 790 requests

node 1, 2, 3 + Linode Load Balancer = 1,988 requests

1
Können Sie das error_log so anpassen, dass die Protokolleinträge beim Herunterfahren von App-a-3 debuggt und veröffentlicht werden?
Giovanni Tirloni

1
Ja, ich werde so schnell wie möglich posten.
Mike Purcell

1
Es ist interessant zu wissen, dass nginx 3 Sekunden (siehe Zeile 71-85) damit verbracht hat, zu erkennen, dass der Upstream-Server offline ist, und dann 3 Sekunden (erneut) (siehe Zeile 95-118), um Inhalte von einem anderen Upstream abzurufen.
Masegaloeh

Damit habe ich zu kämpfen. Ich habe den Eindruck, dass nginx über einen Black-Box-Algorithmus verfügt, mit dem festgestellt werden kann, ob ein Upstream-Server ausgefallen ist. Wenn dies der Fall ist, senden Sie ihm für X Sekunden keine weitere Anfrage.
Mike Purcell

1
Würden Sie einfach Nginx aktualisieren? Es hört sich so an, als würde es sich nicht so verhalten, wie es sollte, und seitdem wurden viele Leistungsverbesserungen vorgenommen.
Mürrisch

Antworten:


5

Wenn nginx eine Anfrage an einen geschlossenen Port auf einem Server mit einem funktionierenden IP-Stack sendet, erhält es sofort eine negative Bestätigung. Wenn dort kein Server zum Antworten vorhanden ist (oder wenn Sie das eingehende Paket an einer Firewall ablegen), müssen Sie warten, bis die Verbindung unterbrochen ist.

Die meisten Load Balancer verfügen über einen Abfragemechanismus und / oder einen Heartbeat, um präventiv nach einem ausgefallenen Server zu suchen. Vielleicht möchten Sie diese Optionen prüfen. Das Abrufen wird normalerweise nicht mehr als ein- oder zweimal pro Minute für einen Webserver ausgeführt. Eine Heartbeat-Überprüfung auf Serverausfälle kann jedoch jede Sekunde oder so erfolgen.

Nginx ist nicht der fortschrittlichste Load Balancer. Wenn Sie in diese Art von Problem geraten, sollten Sie sich andere Optionen ansehen.

EDIT: So etwas vielleicht? http://www.howtoforge.com/setting-up-a-high-availability-load-balancer-with-haproxy-heartbeat-on-debian-lenny . Für eine kleinere Installation sind keine separaten Server erforderlich. Legen Sie sie einfach auf die Webserverboxen. Das gibt Lastausgleich, aber kein Caching. Es gibt auch HA-Lösungen, die Tintenfische oder Lacke als Reaktion auf einen Herzschlag kontrollieren.


Da wir gerade Bootstrapping betreiben, können wir uns derzeit keinen kommerziellen Load Balancer wie einen F5 leisten, vielleicht nach Abschluss der ersten Runde. Was ich nicht verstehe, ist, warum die passiven Prüfungen max_failsund fail_timeoutAnweisungen nicht zu funktionieren scheinen. Laut nginx docs ( nginx.org/en/docs/http/… ) ist der aktive Gesundheitscheck verfügbar, jedoch nur mit einem "kommerziellen Abonnement" für 1.350 USD pro Jahr. Sicherlich musste jemand anderes auf dieses Szenario gestoßen sein.
Mike Purcell

@MikePurcell Meine Antwort wurde bearbeitet, um einen wahrscheinlichen alternativen Software-Loadbalancer aufzunehmen.
mc0e

1
Wenn Sie nur 3 Upstream-Server haben, wäre ein Hardware-Load-Balancer übertrieben, selbst wenn das Budget vorhanden wäre. Schauen Sie sich HAproxy an.
mc0e

Offensichtlich bin ich auf der Suche nach Skalierbarkeit, also könnten es viele sein, die Straße hinunter. HAProxy ist wirklich nicht der Weg, den ich einschlagen möchte, da ich Nginx bevorzuge, da es mehrere vhosts richtig verarbeiten und zu verschiedenen Clustern umleiten kann.
Mike Purcell

Intuitiv würde ich erwarten, dass Haproxy besser skaliert, aber suchen Sie nach Ergebnissen von jemandem, der es tatsächlich getestet hat. Ob Sie Nginx oder Haproxy verwenden, liegt bei Ihnen, aber der wichtige Teil von dem, was ich gesagt habe, ist, dass Sie einen Herzschlag oder etwas Äquivalentes benötigen.
mc0e


1

In den letzten Wochen habe ich mit dem Pre-Sales-Engineering-Team von NGINX zusammengearbeitet, um das Problem zu beheben, bevor ich den Supportvertrag kaufe. Nach vielem Basteln und Zusammenarbeiten ist die einzige Schlussfolgerung, die wir für die erhöhte Verzögerung vermuten können, wenn ein einzelner Knoten vollständig dunkel wird, dass auf den fraglichen Servern alle den viel älteren Apache 2.2 ausgeführt wurden.

Die NGINX-Ingenieure konnten das Problem mit Apache 2.4.x nicht neu erstellen. Dies wäre meine empfohlene Lösung, wenn jemand anderes auf die gleiche Situation stößt. Für unser Projekt arbeite ich jedoch daran, mich von Apache zu entfernen und NGINX mit php-fpm zu implementieren.

Abschließend wird unsere Umgebung NGINX + (erfordert den Supportvertrag) als Load Balancer verwenden, da Upstream-Knoten Integritätsprüfungen durchführen und Upstream-Knoten, auf denen NGINX (FOSS) ausgeführt wird, Anforderungen per Round-Robin senden können.

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.