2012-07-25 8 views
7

Meine Situation ist, dass wir derzeit eine Online-Anwendung schreiben, die Node.js auf Serverseite mit WebSocket Listener verwendet. Wir haben zwei verschiedene Teile: einer dient Seiten und verwendet node.js und express + ejs, ein anderer ist eine komplett andere App, die nur die socket.io-Bibliothek für Websockets enthält. Also hier kommen wir zu dieser Frage der Skalierbarkeit von Websockets Teil.Cookie-basierter Lastenausgleich für WebSockets?

Eine Lösung, die wir gefunden haben, ist Redis zu verwenden und Socket-Informationen zwischen Servern zu teilen, aber aufgrund der Architektur wird es die gemeinsame Nutzung von vielen anderen Informationen erfordern, was einen enormen Overhead auf den Servern verursachen wird.

Nach diesem Intro ist meine Frage - ist es möglich, Cookie-basierten Lastenausgleich für WebSockets zu verwenden? Das heißt, jede Verbindung von Benutzer mit Cookie Server = Server1 wird immer an Server1 weitergeleitet und jede Verbindung mit Cookie Server = Server2 wird Fw zu Server2 und die Verbindung mit keinem solchen Cookie wird FW zu den am wenigsten ausgelasteten Server sein.

UPDATE: Wie eine "Antwort" sagt - ja, ich weiß, dass das existiert. Ich kann mich nur nicht erinnern, dass dieser Name eine Session ist. Aber die Frage ist - wird das für WebSockets funktionieren? Gibt es mögliche Komplikationen?

+0

Dies ist eine Frage, die mich auch sehr interessiert, nur sehe ich nicht das Problem mit Load-Balancing eingehenden Verbindungen von den Browsern (es wird nur einen der Server treffen und dabei bleiben), ich Ich bin mehr daran interessiert, wie Sie von Ihrem Backend aus auf diese Server zugreifen. Wie, ich habe den Backend-Server, der die eigentliche Arbeit erledigt und dann wird es Nachrichten an websockets Server über einen Socket schieben - woher weiß ich, an welchen man drücken muss, wenn ich einen Cluster habe? Meine derzeitige Idee ist, die Liste aller offenen Verbindungen irgendwo im zentralen db zu behalten, nicht sicher, ob es der beste Weg ist. – KOHb

+0

@ KOHb Ich habe kein zusätzliches Backend hinter Socket-Servern. So ist es in meinem Fall viel einfacher. Aber von dem, was Sie sagen, würde ich Redis Server für diesen Zweck versuchen. – AlexKey

Antwort

5

Wir hatten ein ähnliches Problem in unserem Node.js Produktions-Stack. Wir haben zwei Server, die WebSockets verwenden, die für normale Anwendungsfälle funktionieren, aber gelegentlich würde der Load Balancer diese Verbindung zwischen den beiden Servern zurückwerfen, was zu Problemen führen würde. (Wir haben Session-Code im Backend, der es hätte beheben müssen, aber nicht richtig behandelt.)

Wir versuchten Sticky Session auf dem Barracuda Load Balancer vor diesen Servern zu aktivieren, aber festgestellt, dass es WebSocket blockieren würde Verkehr aufgrund seiner Funktionsweise. Ich habe nicht genau untersucht, warum so wenig Informationen online verfügbar sind, aber es scheint, dass dies darauf zurückzuführen ist, wie der Balancer die Header für eine HTTP-Anfrage entfernt, den Cookie ergreift und die Anfrage an den richtigen Backend-Server weiterleitet. Da WebSockets zunächst als HTTP, dann aber als Upgrade gestartet wird, hat der Load Balancer den Unterschied in der Verbindung nicht bemerkt und versucht, dieselbe HTTP-Verarbeitung auszuführen. Dies würde dazu führen, dass die WebSocket-Verbindung fehlschlägt und der Benutzer getrennt wird.

Das Folgende ist, was wir zur Zeit haben, die sehr gut funktioniert. Wir verwenden immer noch die Barracuda Load Balancer vor unseren Backend Servern, aber wir haben keine Sticky Sessions auf den Load Balancern aktiviert. Auf unseren Backend-Servern befindet sich vor unserem Anwendungsserver HAProxy, der WebSockets ordnungsgemäß unterstützt und Sticky-Sitzungen auf "Umwegen" bereitstellen kann.


Anfrage Flussliste

  1. Incoming Anfrage Kunde trifft primäre Barracuda Load Balancer
  2. Load Balancer nach vorne, um entweder der aktiven Backend-Server
  3. HAProxy die Anfrage und prüft, ob die erhält neuer 'sticky cookie'
  4. Basierend auf dem Cookie leitet HAProxy den richtigen Backend-Anwendungsserver weiter

anfordern Flussdiagramm

WebSocket Request /--> Barracuda 1 -->\ /--> Host 1 -->\ /--> App 1 
------------------->      -->    --> 
        \--> Barracuda 2 -->/ \--> Host 2 -->/ \--> App 1 

Wenn die Pfeile auf eine Anfrage zurückkommen, welche die Anforderungsmittel an jeder Stelle in der Strömung fließen kann.


HAProxy Konfigurationsdetails

backend app_1 
    cookie ha_app_1 insert 
    server host1 10.0.0.101:80011 weight 1 maxconn 1024 cookie host_1 check 
    server host2 10.0.0.102:80011 weight 1 maxconn 1024 cookie host_2 check 

In der obigen Konfiguration:

  • cookie ha_app_1 insert ist der eigentliche Cookie-Namen
  • verwendet
  • cookie host_1 check oder cookie host_2 check setzt den Cookie-Wert
+0

Vielen Dank für diese detaillierte Antwort. Aber leider müssen wir immer noch eine sticky-Sitzung für die Socket-Verbindung verwenden. Benutzt du die Leitung oder lenkst du sie um? – AlexKey

+0

Aufgrund der Ergebnisse im WebSocket-Protokoll haben wir uns für folgende Lösung entschieden: - Load-Balance-Socket-Verbindung auf handhsake Schritt (es ist in Ordnung, da Handshake nur HTTP ist) mit sticky Sitzung und nicht Proxy-Leitung, aber umleiten - Im Fall wenn Statusänderungen - Erzwinge-Wiederverbinden-Client, wo es wieder auf den richtigen Server auf Handshake ausgeglichen wird - Server innerhalb Sub-Domain-Netzwerk (smth wie s1-socket.example.com, s2-socket.example.com etc) ausgesetzt Aber wir haben noch keine Implementierung an Ort und Stelle. Ich werde dich aktualisieren, sobald wir es haben. – AlexKey

+0

Ihr erster Kommentar: Wir müssen immer noch Sticky-Sessions verwenden, und die obige Antwort ist, wie wir Sticky Sessions auf unsere eigene Art implementiert haben, die die Sticky Session-Nutzung des Load Balancer umgangen hat. Ihr zweiter Kommentar: Das klingt wie ein Szenario, das für Sie arbeiten sollte. Es ist immer noch sehr ähnlich zu unserem, obwohl der Hardware Load Balancer nicht verwendet wird.Wir verwenden HAProxy als unseren einzigen Lastenausgleich, der die benötigte Funktionalität bietet. –