haproxy: Beibehaltung bestehender Sitzungen unter hoher Last und Bereitstellung von "503" für Neuankömmlinge


12

Versuchen Sie, das zu tun, was im Titel steht: Beibehalten vorhandener Sitzungen unter hoher Last und Versenden von 503-Nachrichten an neu angekommene Besucher.

Problem: Es funktioniert, aber die Sitzungen dauern nicht länger als 90 Sekunden.

Bei den aktuellen Ergebnissen frage ich mich, ob eine Zeitüberschreitung vorliegt, die mir fehlt.

Zweck

Ich versuche, Haproxy zu bekommen:

  • Senden Sie Anforderungen für neue Sitzungen an das Backend-001, wenn die Gesamtzahl der Sitzungen im Frontend einen bestimmten Schwellenwert unterschreitet.
  • Bereitstellen eines 503-Fehlers für neue Sitzungen, wenn die Gesamtzahl der Sitzungen im Frontend diesen Schwellenwert überschreitet
  • Zulassen von Anforderungen für vorhandene Sitzungen, auch wenn die Anzahl der Sitzungen den Schwellenwert überschreitet

Auf diese Weise werden Besucher, die gerade ein mehrstufiges Formular ausfüllen, nicht von einem 503-Fehler überrascht, und neue Besucher können aufgefordert werden, "später wiederzukommen, da wir gerade sehr beschäftigt sind".

Installieren

Das Setup ist wie folgt:

            {visitors}
                ↓ 
            [haproxy]
                ↓ 
[rails app on unicorn served by nginx]   (right now just one 
                                            backend: 'backend-001')

aktueller Ansatz

Um dies zu erreichen, verwende ich die unten stehende Konfiguration.

Diese dient zum Testen mit einer sehr niedrigen Grenze (10 Anschlüsse am Front-End (fe_conn gt 10)), um das Testen zu vereinfachen.

Um den Server etwas zu belasten, benutze ich httperf wie folgt:

httperf --hog --server staging.machine.tld --uri / do_some_things --wsess = 500,10,30 --rate 2

global
    daemon
    maxconn 10000

defaults
    mode        http
    timeout connect 6s
    timeout client  60s
    timeout server  60s
    balance roundrobin
    option http-server-close

frontend http-in
    bind [PUBLIC_IP]:80

    default_backend backend-001

    acl too_many fe_conn gt 10
    use_backend b_too_many if too_many

backend backend-001
    fullconn 10
    appsession _session_id len 128 timeout 7200s

    cookie SERVERID insert maxidle 7200s
    server Server1 127.0.10.1:80 cookie backend-001 check

backend b_too_many
    errorfile 503 /var/www/50x.html

Problem

Wie oben erwähnt, ist das Problem: Es funktioniert fast, aber die Sitzungen dauern nicht länger als etwa 90 Sekunden.

Wenn Sie weiter klicken, können Sie Ihre Sitzung auch dann fortsetzen, wenn 10 Sitzungen belegt sind.

Wenn Sie versuchen, eine Seite auf dem Server mit einer anderen Browserinstanz zu öffnen, wird der 503-Fehler angezeigt.

Es sieht also so aus, als wäre ich fast da. Hat jemand eine Idee, was die kurzen Sitzungszeiten verursachen könnte?

Und vor allem, wie ich das beheben kann :)

(edit: 'weight 1 maxconn 10' von der 'server'-Zeile entfernt, nicht relevant und könnte verwirren)


Könnte eine dumme Frage sein - was ist die keep_alive Einstellung in Nginx? Anscheinend sind es standardmäßig 75er - könnte das das Problem sein?
Aidan Kane

Antworten:


4

Leider scheinen Sie Verbindungen mit Sitzungen auf Anwendungsebene völlig zu verwechseln. Ein Benutzer, der die Site besucht, hat möglicherweise ein Cookie, das Sie glauben lässt, eine Verbindung zu ihm zu besitzen, obwohl dies nicht unbedingt der Fall ist. Möglicherweise öffnet er so viele Verbindungen wie erforderlich, um Objekte abzurufen und durch Seiten zu navigieren.

Die 90 Sekunden, die Sie mit Sicherheit beobachten, sind die Wartezeiten des Browsers für inaktive Verbindungen.

Es ist möglich, das zu erreichen, was Sie wollen, aber es ist etwas komplexer, da Sie auch das Vorhandensein des Persistenz-Cookies in der Anfrage berücksichtigen müssen, um herauszufinden, ob der Besucher neu ist oder nicht.

Außerdem ist es im Allgemeinen effizienter, sich auf die durchschnittliche Anzahl von Serververbindungen als auf die Anzahl der Frontend-Verbindungen zu verlassen. Der Grund ist, dass Sie diese Zahl neu einstellen müssen, wenn ein Server ausfällt. Am effizientesten ist es, einen Wert für "server maxconn" einzurichten, um die Warteschlange zu aktivieren, und "avg_queue" zu verwenden, damit das Limit für die durchschnittliche Anzahl der Anforderungen in der Warteschlange auf Servern gilt. Auf diese Weise können Sie bekannte Besucher korrekt behandeln und gleichzeitig neue Benutzer sanft in ein anderes Backend verschieben, wenn die Auslastung aufgrund vorhandener Besucher zunimmt.


1
Danke Danke! Das hat viel aufgeklärt. Ich habe es jetzt funktioniert, indem ich (unter anderem) das Backend-Cookie mit hdr_sub überprüfe (also "hdr_sub (cookie) SERVERID = backend-001"). Ich werde eine funktionierende Konfiguration posten, wenn sie fertig ist.
Apenootje,
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.