Lastausgleichs-Web-Sockets


104

Ich habe eine Frage zum Laden von Web-Sockets.

Ich habe einen Server, der Web-Sockets unterstützt. Browser stellen eine Verbindung zu meiner Website her und jeder öffnet einen Web-Socket für www.mydomain.com. Auf diese Weise kann meine App für soziale Netzwerke Nachrichten an die Kunden senden.

Wenn ich nur HTTP-Anforderungen verwende, skaliere ich traditionell, indem ich einen zweiten Server und einen Load Balancer vor den beiden Webservern hinzufüge.

Bei Web-Sockets muss die Verbindung direkt mit dem Webserver erfolgen, nicht mit den Load Balancern. Wenn ein Computer ein physisches Limit von beispielsweise 64.000 offenen Ports hat und die Clients eine Verbindung zum Load Balancer herstellen, kann ich dies nicht unterstützen mehr als 64.000 gleichzeitige Benutzer.

Also wie mache ich -

  1. den Client dazu bringen, beim Laden der Seite eine direkte Verbindung zum Webserver (und nicht zum Load Balancer) herzustellen? Lade ich einfach das JavaScript von einem Knoten und die Load Balancer (oder was auch immer) ändern die URL für das Skript zufällig jedes Mal, wenn die Seite zum ersten Mal angefordert wird?

  2. einen Wellenstart bewältigen? Der Browser wird feststellen, dass die Verbindung geschlossen wird, wenn der Webserver heruntergefahren wird. Ich kann JavaScript-Code schreiben, um zu versuchen, die Verbindung wieder zu öffnen, aber der Knoten wird für eine Weile weg sein. Ich müsste also zum Load Balancer zurückkehren, um die Adresse des nächsten zu verwendenden Knotens abzufragen.

  3. Ich habe mich gefragt, ob die Load Balancer bei der ersten Anforderung eine Umleitung senden, sodass der Browser zunächst eine Umleitung anfordert www.mydomain.comund zu dieser umgeleitet wird www34.mydomain.com. Das funktioniert ganz gut, bis der Knoten ausfällt - und Websites wie Facebook tun das nicht. Wie machen Sie das?


1
Sie können den Lastausgleich auf Netzwerkebene durchführen, wie hier
Chris Snow,

1
Es gibt auch alternative Ansätze wie DNS-basierten Lastausgleich oder die Verwendung eines http-basierten Orchestrierungsservers. Ich habe versucht, die Vor- und Nachteile jedes Ansatzes unter deepstream.io/blog/load-balancing-websocket-connections
wolframhempel

@ Wolframhempel Link ist tot. :-(
Emile Cormier

Antworten:


94

Fügen Sie einen L3-Load-Balancer ein, der IP-Pakete basierend auf dem Quell-IP-Port-Hash an Ihre WebSocket-Serverfarm verteilt. Da der L3-Balancer keinen Status beibehält (unter Verwendung eines gehashten Quell-IP-Ports), wird er auf die Kabelgeschwindigkeit auf Low-End-Hardware (z. B. 10 GbE) skaliert. Da die Verteilung deterministisch ist (unter Verwendung des gehashten Quell-IP-Ports), funktioniert sie mit TCP (und damit WebSocket).

Beachten Sie auch, dass ein 64-KB-Hard-Limit nur für ausgehende TCP / IP für eine bestimmte (Quell-) IP-Adresse gilt. Dies gilt nicht für eingehende TCP / IP. Wir haben Autobahn (einen Hochleistungs-WebSocket-Server) mit 200.000 aktiven Verbindungen auf einer 2-Kern-VM mit 4 GB RAM getestet .

Beachten Sie auch, dass Sie den L7-Lastausgleich für den HTTP-Pfad durchführen können, der beim ersten WebSocket-Handshake angekündigt wurde. In diesem Fall muss der Load Balancer den Status beibehalten (welches Quell-IP-Port-Paar geht zu welchem ​​Backend-Knoten). Es wird wahrscheinlich trotzdem auf Millionen von Verbindungen skaliert, wenn es anständig eingerichtet ist.

Haftungsausschluss: Ich bin Originalautor von Autobahn und arbeite für Tavendo.


Ich würde also meine Javascript-Bibliothek von der Load-Balancer-URL laden und die Load-Balancer-URL angeben, wenn ich den Web-Socket in Javascript erstelle - Sie meinen, er ist für den Browser transparent? Das ist cool!
John Smith

1
Ja, es gibt nur 1 URL, und der Hostname der letzteren sollte in Ihren Load-Balancer aufgelöst werden. Der WebSocket-Backend-Server verfügt über interne IP-Adressen (nicht öffentlich) und kann optional auch auf anderen als den öffentlichen Ports ausgeführt werden. Die einzige Einschränkung besteht darin, dass Sie den WebSocket-Servern möglicherweise mitteilen müssen, wie ihr öffentlich sichtbarer Hostname, ihre IP-Adresse und ihr Port lauten, da konforme WebSocket-Server überprüfen, ob die im HTTP-Header des WS-Handshakes angegebene URL mit dem Hostnamen / der IP / dem Port übereinstimmt, den sie haben hören zu.
Oberstet

Ich habe nicht viele Websocket-Verbindungen zum Ausgleichen, aber ich habe viel Verkehr in einer oder sage nur sehr wenige Verbindungen. Sagen Sie der Einfachheit halber jetzt eine Verbindung. Wie kann ich die Anforderungen über eine Web-Socket-Verbindung ausgleichen?
user1870400

Wenn ich mehr Verbindungen 5000+ im Java-Websocket herstelle, wird kein Speicher freigegeben. Gibt es eine Lösung?
Poonam Patel

3

Beachten Sie, dass Sie, wenn Ihre Websocket-Serverlogik auf NodeJS mit Socket.io ausgeführt wird, Socket.io anweisen können, einen gemeinsam genutzten Redis-Schlüssel- / Wertspeicher für die Synchronisierung zu verwenden. Auf diese Weise müssen Sie sich nicht einmal um den Load Balancer kümmern. Ereignisse werden zwischen den Serverinstanzen übertragen.

var io = require('socket.io')(3000);
var redis = require('socket.io-redis'); 
io.adapter(redis({ host: 'localhost', port: 6379 }));

Siehe: http://socket.io/docs/using-multiple-nodes/

Aber irgendwann kann Redis zum Engpass werden ...


2

Sie können auch einen Lastausgleich der Schicht 7 mit Inspektions- und "Routing-Funktionen" erzielen.

Weitere Informationen finden Sie unter "Überprüfen und Lastausgleich des WebSockets-Datenverkehrs mit Stingray Traffic Manager und bei Bedarf Verwalten des WebSockets- und HTTP-Datenverkehrs, der über dieselbe IP-Adresse und denselben Port empfangen wird." https://splash.riverbed.com/docs/DOC-1451


2
Ich musste ein bisschen nachsehen, um die Informationen zu finden, die Sie verlinkt haben. Die Wayback-Maschine hat mir geholfen, eine Live-Kopie dieses Artikels zu finden: community.pulsesecure.net/t5/Pulse-Secure-vADC/…
Wyck
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.