Aktivieren HTTP-Reverse-Proxys normalerweise HTTP Keep-Alive auf der Clientseite der Proxy-Verbindung und nicht auf der Serverseite?

30

HAProxy hat die Möglichkeit, HTTP-Keep-Alive auf der Clientseite (Client <-> HAProxy) zu aktivieren, aber auf der Serverseite (HAProxy <-> Server) zu deaktivieren.

Einige unserer Kunden stellen über Satellit eine Verbindung zu unserem Webservice her, sodass die Latenz ca. 600 ms beträgt, und ich denke, dass die Aktivierung von Keep-Alive die Dinge etwas beschleunigen wird. Habe ich recht?

Wird dies von Nginx unterstützt? Ist diese Funktion in anderen Software- und Hardware-Load-Balancern weit verbreitet? Was außer HAProxy noch?

LostInComputer
quelle

Antworten:

43

edit: Meine Antwort deckt nur die ursprüngliche unbearbeitete Frage ab, ob dies typisch für Load Balancer / Reverse Proxies ist. Ich bin mir nicht sicher, ob Nginx / Product X dies unterstützt. 99,9% meiner Erfahrungen mit Reverse-Proxys sind mit HAproxy verbunden.

Richtig. HTTP Keep-Alive auf der Client-Seite, aber nicht auf der Server-Seite.

Warum?

Wenn Sie ein paar Details aufschlüsseln, können Sie schnell erkennen, warum dies von Vorteil ist. Nehmen wir für dieses Beispiel an, wir laden eine Seite www.example.com und diese Seite enthält 3 Bilder, img [1-3] .jpg.

Browser lädt eine Seite ohne Keep-Alive

  1. Der Client stellt über Port 80 eine TCP-Verbindung zu www.example.com her
  2. Client führt eine HTTP-GET-Anforderung für "/" aus
  3. Server sendet den HTML-Inhalt der URI "/" (einschließlich HTML-Tags, die auf die 3 Bilder verweisen)
  4. Server schließt die TCP-Verbindung
  5. Der Client stellt über Port 80 eine TCP-Verbindung zu www.example.com her
  6. Client führt eine HTTP-GET-Anforderung für "/img1.jpg" aus
  7. Server sendet das Bild
  8. Server schließt die TCP-Verbindung
  9. Der Client stellt über Port 80 eine TCP-Verbindung zu www.example.com her
  10. Client führt eine HTTP-GET-Anforderung für "/img2.jpg" aus
  11. Server sendet das Bild
  12. Server schließt die TCP-Verbindung
  13. Der Client stellt über Port 80 eine TCP-Verbindung zu www.example.com her
  14. Client führt eine HTTP-GET-Anforderung für "/img3.jpg" aus
  15. Server sendet das Bild
  16. Server schließt die TCP-Verbindung

Beachten Sie, dass 4 separate TCP-Sitzungen eingerichtet und dann geschlossen wurden.

Browser lädt eine Seite mit Keep-Alive

HTTP Keep-Alive ermöglicht, dass eine einzelne TCP-Verbindung mehrere HTTP-Anforderungen nacheinander bedient.

  1. Der Client stellt über Port 80 eine TCP-Verbindung zu www.example.com her
  2. Der Client führt eine HTTP-GET-Anforderung für "/" aus und fordert den Server auf, dies zu einer HTTP-Keep-Alive-Sitzung zu machen.
  3. Server sendet den HTML-Inhalt der URI "/" (einschließlich HTML-Tags, die auf die 3 Bilder verweisen)
  4. Server schließt die TCP-Verbindung nicht
  5. Client und HTTP-GET-Anforderung für "/img1.jpg"
  6. Server sendet das Bild
  7. Client und HTTP-GET-Anforderung für "/img2.jpg"
  8. Server sendet das Bild
  9. Client und HTTP-GET-Anforderung für "/img3.jpg"
  10. Server sendet das Bild
  11. Der Server schließt die TCP-Verbindung, wenn innerhalb des HTTP-Keep-Alive-Zeitlimits keine HTTP-Anforderungen mehr empfangen werden

Beachten Sie, dass mit Keep-Alive nur 1 TCP-Verbindung hergestellt und schließlich geschlossen wird.

Warum ist Keep-Alive besser?

Um dies zu beantworten, müssen Sie wissen, was zum Herstellen einer TCP-Verbindung zwischen einem Client und einem Server erforderlich ist. Dies wird als TCP-3-Wege-Handshake bezeichnet.

  1. Der Client sendet ein SYN (Chronise) -Paket
  2. Der Server sendet ein SYN (chronise) ACK (nowledgement), SYN-ACK, zurück
  3. Der Client sendet ein ACK-Paket (Nowledgement)
  4. Die TCP-Verbindung wird jetzt sowohl vom Client als auch vom Server als aktiv betrachtet

Netzwerke haben eine Latenz, sodass jeder Schritt im 3-Wege-Handshake eine gewisse Zeit in Anspruch nimmt. Nehmen wir an, dass zwischen Client und Server 30 ms liegen. Wenn IP-Pakete zum Herstellen der TCP-Verbindung hin und her gesendet werden, dauert der Aufbau einer TCP-Verbindung 3 x 30 ms = 90 ms.

Das hört sich vielleicht nicht nach viel an, aber wenn wir bedenken, dass wir in unserem ursprünglichen Beispiel 4 separate TCP-Verbindungen herstellen müssen, werden dies 360 ms. Was ist, wenn die Latenz zwischen Client und Server 100 ms statt 30 ms beträgt? Dann brauchen unsere 4 Verbindungen 1200ms, um sich zu etablieren.

Schlimmer noch, für das Laden einer typischen Webseite sind möglicherweise weit mehr als nur drei Bilder erforderlich. Möglicherweise sind mehrere CSS-, JavaScript-, Bild- oder andere Dateien vorhanden, die der Client anfordern muss. Wenn die Seite 30 andere Dateien lädt und die Client-Server-Latenz 100 ms beträgt, wie lange müssen wir dann TCP-Verbindungen herstellen?

  1. Der Aufbau einer TCP-Verbindung dauert 3 x Latenz, dh 3 x 100 ms = 300 ms.
  2. Wir müssen dies 31 Mal tun, einmal für die Seite und weitere 30 Mal für jede andere Datei, auf die von der Seite verwiesen wird. 31 x 300 ms = 9,3 Sekunden.

9,3 Sekunden für den Aufbau von TCP-Verbindungen zum Laden einer Webseite, die auf 30 andere Dateien verweist. Dabei wird nicht einmal die Zeit gezählt, die zum Senden von HTTP-Anforderungen und zum Empfangen von Antworten aufgewendet wurde.

Mit HTTP Keep-Alive müssen wir nur 1 TCP-Verbindung herstellen, was 300 ms dauert.

Wenn HTTP Keep-Alive so großartig ist, warum nicht auch auf der Serverseite?

HTTP-Reverse-Proxys (wie HAproxy) werden in der Regel sehr nahe an den Back-End-Servern bereitgestellt, für die sie einen Proxyserver einrichten. In den meisten Fällen beträgt die Latenz zwischen dem Reverse-Proxy und seinen Back-End-Servern weniger als 1 ms, sodass der Aufbau einer TCP-Verbindung viel schneller ist als zwischen einem Client.

Das ist aber nur der halbe Grund. Ein HTTP-Server weist jeder Client-Verbindung eine bestimmte Menge an Speicher zu. Mit Keep-Alive wird die Verbindung aufrechterhalten und im weiteren Verlauf wird eine bestimmte Menge an Speicher auf dem Server belassen, bis das Keep-Alive-Zeitlimit erreicht ist, das je nach Serverkonfiguration bis zu 15 Sekunden betragen kann .

Wenn wir also die Auswirkungen der Verwendung von Keep-Alive auf der Serverseite eines HTTP-Reverse-Proxys berücksichtigen, erhöhen wir den Speicherbedarf. Da jedoch die Latenz zwischen dem Proxy und dem Server so gering ist, profitieren wir nicht wirklich von der Verkürzung der Zeit, die für den 3-Wege-Handshake von TCP benötigt wird. In diesem Szenario ist es normalerweise besser, Keep-Alive zwischen dem Proxy und dem Webserver zu deaktivieren.

Haftungsausschluss: Ja, diese Erklärung berücksichtigt nicht die Tatsache, dass Browser in der Regel mehrere HTTP-Verbindungen zu einem Server gleichzeitig herstellen. Es gibt jedoch eine Begrenzung für die Anzahl der parallelen Verbindungen, die ein Browser zum selben Host herstellt, und diese ist in der Regel immer noch klein genug, um Keep-Alive wünschenswert zu machen.

ThatGraemeGuy
quelle
5
Ein großes Lob für die hervorragende Erklärung, Graeme, ich habe nie genug Zeit für eine so lange Antwort auf die Frage aufgewendet, und ich werde auf jeden
Fall
2
Wäre es für keepAlive auf der Serverseite von Vorteil, wenn die Verbindung zwischen Proxy und Backend https wäre?
Avmohan
"Ein HTTP-Server reserviert für jede Client-Verbindung eine bestimmte Menge an Speicher" ja, aber es gibt nur wenige dieser Verbindungen (?) Nur eine pro Load-Balancer? Nicht einer pro Kunde im Internet (?)
Raedwald
@Raedwald, wenn Ihr Lastenausgleich auf das Herstellen einer einzelnen HTTP-Verbindung zu jedem gesicherten Server beschränkt ist, haben Sie eine ziemlich schlechte Zeit. :-)
ThatGraemeGuy
7

Nginx unterstützt beidseitiges Keep-Alive.

VBart
quelle
Würden Sie sagen, dass Keep Alive für Backends nützlich ist, wenn zwischen Proxy und Backends eine Latenz bestand? Auch was würde eine optimale Anzahl von Keep-Alive-Verbindungen erlauben?
CMCDragonkai
@CMCDragonkai Wenn sich Ihre Backends auf dedizierten Servern befinden, kann es hilfreich sein, die Verbindungslatenz zu vermeiden, die von Ihrem Netzwerk abhängt. Es gibt keinen goldenen Mittelwert, die optimale Anzahl hängt hauptsächlich von Ihrem Setup, Ihrer Umgebung, Ihrer Anwendung und Ihrem Anforderungsmuster ab.
VBart
Ich hoffe, eine Gleichung zu finden, um das zu lösen!
CMCDragonkai
2
Die Frage, wie ich sie lese, lautet nicht, ob nginx Keep-Alive auf der Upstream-Seite unterstützt, sondern ob nginx das Deaktivieren von Keep-Alive auf der Upstream-Seite unterstützt.
User45793