Unterhalten HTML WebSockets für jeden Client eine offene Verbindung? Ist diese Skala?

159

Ich bin gespannt, ob jemand Informationen zur Skalierbarkeit von HTML WebSockets hat. Nach allem, was ich gelesen habe, scheint jeder Client eine offene Kommunikationslinie mit dem Server aufrechtzuerhalten. Ich frage mich nur, wie sich das skalieren lässt und wie viele offene WebSocket-Verbindungen ein Server verarbeiten kann. Vielleicht ist es in der Realität kein Problem, diese Verbindungen offen zu lassen, aber es fühlt sich so an.

Ryan Montgomery
quelle
1
Es gibt kein HTML-WebSocket. Sie meinen HTTP WebSocket.
Marquis von Lorne

Antworten:

209

In den meisten Fällen werden WebSockets wahrscheinlich besser skaliert als AJAX / HTML-Anforderungen. Dies bedeutet jedoch nicht, dass WebSockets ein Ersatz für alle Verwendungen von AJAX / HTML ist.

Jede TCP-Verbindung an sich verbraucht nur sehr wenig Serverressourcen. Oft kann das Einrichten der Verbindung teuer sein, aber das Aufrechterhalten einer inaktiven Verbindung ist fast kostenlos. Die erste Einschränkung, die normalerweise auftritt, ist die maximale Anzahl von Dateideskriptoren (Sockets verbrauchen Dateideskriptoren), die gleichzeitig geöffnet werden können. Dies ist häufig standardmäßig 1024, kann aber leicht höher konfiguriert werden.

Haben Sie jemals versucht, einen Webserver so zu konfigurieren, dass Zehntausende von AJAX-Clients gleichzeitig unterstützt werden? Ändern Sie diese Clients in WebSockets-Clients, und dies ist möglicherweise möglich.

HTTP-Verbindungen erstellen zwar über einen längeren Zeitraum keine offenen Dateien oder verbrauchen keine Portnummern, sind jedoch in nahezu jeder anderen Hinsicht teurer:

  • Jede HTTP-Verbindung enthält viel Gepäck, das die meiste Zeit nicht verwendet wird: Cookies, Inhaltstyp, Länge des Inhalts, Benutzeragent, Server-ID, Datum, letzte Änderung usw. Sobald eine WebSockets-Verbindung hergestellt wurde, wird nur die Die für die Anwendung erforderlichen Daten müssen hin und her gesendet werden.

  • In der Regel sind HTTP-Server so konfiguriert, dass sie den Start und den Abschluss jeder HTTP-Anforderung protokollieren, die Festplatten- und CPU-Zeit beansprucht. Es wird zum Standard, den Start und die Fertigstellung von WebSockets-Daten zu protokollieren. Während die WebSockets-Verbindung eine Duplexübertragung durchführt, entsteht kein zusätzlicher Protokollierungsaufwand (außer von der Anwendung / dem Dienst, wenn dies vorgesehen ist).

  • In der Regel werden interaktive Anwendungen, die AJAX verwenden, entweder kontinuierlich abgefragt oder verwenden einen Mechanismus für lange Abfragen. WebSockets ist eine viel sauberere (und ressourcenärmere) Methode, um ein Ereignismodell zu erstellen, bei dem sich Server und Client gegenseitig benachrichtigen, wenn sie über die vorhandene Verbindung etwas zu berichten haben.

  • Die meisten gängigen Webserver in der Produktion verfügen über einen Pool von Prozessen (oder Threads) zur Verarbeitung von HTTP-Anforderungen. Mit zunehmendem Druck wird die Größe des Pools erhöht, da jeder Prozess / Thread jeweils eine HTTP-Anforderung verarbeitet. Jeder zusätzliche Prozess / Thread benötigt mehr Speicher und das Erstellen neuer Prozesse / Threads ist erheblich teurer als das Erstellen neuer Socket-Verbindungen (was diese Prozesse / Threads noch tun müssen). Die meisten der gängigen WebSockets-Server-Frameworks gehen den Weg des Ereignisses, der tendenziell skaliert und eine bessere Leistung erzielt.

Der Hauptvorteil von WebSockets sind Verbindungen mit geringerer Latenz für interaktive Webanwendungen. Es lässt sich besser skalieren und verbraucht weniger Serverressourcen als HTTP AJAX / Long-Poll (vorausgesetzt, die Anwendung / der Server ist ordnungsgemäß konzipiert). Eine geringere Latenzzeit von IMO ist jedoch der Hauptvorteil von WebSockets, da neue Klassen von Webanwendungen aktiviert werden, die nicht möglich sind mit dem aktuellen Overhead und der Latenz von AJAX / Long-Poll.

Sobald der WebSockets-Standard fertiggestellt ist und eine breitere Unterstützung bietet, ist es sinnvoll, ihn für die meisten neuen interaktiven Webanwendungen zu verwenden, die häufig mit dem Server kommunizieren müssen. Bei vorhandenen interaktiven Webanwendungen hängt es wirklich davon ab, wie gut das aktuelle AJAX / Long-Poll-Modell funktioniert. Der Aufwand für die Konvertierung ist nicht trivial, sodass sich die Kosten in vielen Fällen einfach nicht lohnen.

Update :

Nützlicher Link: 600.000 gleichzeitige Websocket-Verbindungen unter AWS mit Node.js.

Kanaka
quelle
4
Super anser. Vielen Dank, dass Sie sich die Zeit genommen haben, um zu antworten.
Ryan Montgomery
7
Ich weiß immer noch nicht, wie ich skalieren soll, wenn du gegen die Wand stößt. Es ist richtig, dass WebSockets weniger Ressourcen verbrauchen (sie werden vertikal skaliert), aber HTTP eignet sich hervorragend für die horizontale Skalierung. Ich kann theoretisch Server hinzufügen, um unendlich zu skalieren. Ich war immer verwirrt darüber, wie man skaliert, wenn man die Kapazität einer einzelnen Box verbraucht. Gedanken?
Sean Clark Hess
6
@ Sean. WebSockets ist bei der horizontalen Skalierung nicht unbedingt schlechter. Es werden nur neue Anwendungen geöffnet, die nicht unbedingt so einfach skaliert werden können. Zum Bereitstellen statischer Daten würde beispielsweise eine Reihe von WebSocket-Servern genauso gut (oder besser) skaliert als eine Reihe von HTTP-Servern. Ein Echtzeitspiel mit geringer Latenz ist unabhängig vom Transport schwer zu skalieren (und mit HTTP einfach nicht realisierbar). Die eigentliche Frage ist, wie gut Sie Daten / Anwendungen skalieren. Wenn dies skaliert, sollte Ihre Wahl zwischen HTTP und WebSockets auf anderen Faktoren beruhen: Latenz, Bereitstellungsoptionen, Browserunterstützung usw.
Kanaka,
2
Eine Korrektur - Eine TCP-Verbindung besteht aus Ziel-IP und Zielport. Das bedeutet, dass das Limit von ± 64.000 Ports NUR für einen einzelnen Client gilt. Theoretisch kann der Server eine beliebige Anzahl offener Verbindungen haben, die NUR durch seine Hardware begrenzt sind.
Rizon
@Rizon, das stimmt. Ich habe die Antwort aktualisiert und die Beschränkung für offene Ports geändert und stattdessen die Beschränkung für Dateideskriptoren erwähnt, auf die häufig zuerst gestoßen wird.
Kanaka
36

Nur eine Klarstellung: Die Anzahl der Clientverbindungen, die ein Server unterstützen kann, hat in diesem Szenario nichts mit Ports zu tun, da der Server [normalerweise] nur auf WS / WSS-Verbindungen an einem einzelnen Port wartet. Ich denke, die anderen Kommentatoren wollten sich auf Dateideskriptoren beziehen. Sie können die maximale Anzahl von Dateideskriptoren ziemlich hoch einstellen, müssen dann aber auf die Socket-Puffergrößen achten, die sich für jeden offenen TCP / IP-Socket addieren. Hier einige zusätzliche Informationen: /server/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

Die verringerte Latenz über WS im Vergleich zu HTTP ist wahr, da HTTP-Header nach dem anfänglichen WS-Handshake nicht mehr analysiert werden. Da immer mehr Pakete erfolgreich gesendet werden, erweitert sich das TCP-Überlastungsfenster und reduziert die RTT effektiv.

Michael
quelle
AFAIR gibt es einen eingehenden Port, aber für jede Verbindung ist immer ein ausgehender Port geöffnet. Dies ist in der Tat nur ein Teil des C10k-Problems .
Arnaud Bouchez
14

Jeder moderne Einzelserver kann Tausende von Clients gleichzeitig bedienen . Die HTTP-Serversoftware muss nur ereignisgesteuert (IOCP) sein (wir sind nicht mehr in der alten Apache-Verbindung = eine Thread- / Prozessgleichung). Sogar der in Windows integrierte HTTP-Server (http.sys) ist IOCP-orientiert und sehr effizient (läuft im Kernel-Modus). Unter diesem Gesichtspunkt gibt es keinen großen Unterschied bei der Skalierung zwischen WebSockets und der regulären HTTP-Verbindung. Eine TCP / IP-Verbindung benötigt eine kleine Ressource (viel weniger als ein Thread), und moderne Betriebssysteme sind für die Verarbeitung vieler gleichzeitiger Verbindungen optimiert: WebSockets und HTTP sind nur Protokolle der OSI 7-Anwendungsschicht, die von diesen TCP / IP-Spezifikationen erben.

Beim Experimentieren habe ich jedoch zwei Hauptprobleme mit WebSockets festgestellt:

  1. Sie unterstützen CDN nicht.
  2. Sie haben potenzielle Sicherheitsprobleme.

Daher würde ich für jedes Projekt Folgendes empfehlen:

  • Verwenden Sie WebSockets nur für Client-Benachrichtigungen (mit einem Fallback-Mechanismus für Langzeitabfragen - es gibt viele Bibliotheken).
  • Verwenden Sie RESTful / JSON für alle anderen Daten, indem Sie ein CDN oder Proxys für den Cache verwenden.

In der Praxis lassen sich vollständige WebSockets-Anwendungen nicht gut skalieren. Verwenden Sie WebSockets einfach für das, wofür sie entwickelt wurden: Benachrichtigungen vom Server an den Client senden.

Informationen zu den potenziellen Problemen bei der Verwendung von WebSockets:

1. Erwägen Sie die Verwendung eines CDN

Heute (fast 4 Jahre später) umfasst die Web-Skalierung die Verwendung von CDN-Frontends ( Content Delivery Network ), nicht nur für statische Inhalte (HTML, CSS, JS), sondern auch für Ihre Anwendungsdaten (JSON) .

Natürlich werden Sie nicht alle Ihre Daten in Ihren CDN-Cache stellen, aber in der Praxis werden sich viele gängige Inhalte nicht oft ändern. Ich vermute, dass 80% Ihrer REST-Ressourcen zwischengespeichert werden können ... Selbst ein CDN-Ablaufzeitlimit von einer Minute (oder 30 Sekunden) kann ausreichen, um Ihrem zentralen Server ein neues Leben zu ermöglichen und die Reaktionsfähigkeit der Anwendung erheblich zu verbessern, da CDN dies kann geografisch abgestimmt sein ...

Meines Wissens gibt es in CDN noch keine WebSockets-Unterstützung, und ich vermute, dass dies niemals der Fall sein wird. WebSockets sind statusbehaftet, während HTTP zustandslos ist und daher sehr einfach zwischengespeichert werden kann. Um WebSockets CDN-freundlich zu machen, müssen Sie möglicherweise zu einem zustandslosen RESTful-Ansatz wechseln, bei dem es sich nicht mehr um WebSockets handelt.

2. Sicherheitsprobleme

WebSockets weisen potenzielle Sicherheitsprobleme auf, insbesondere bei DOS-Angriffen. Beispiele für neue Sicherheitslücken finden Sie in diesen Folien und in diesem Webkit-Ticket .

WebSockets vermeiden die Möglichkeit einer Paketinspektion auf OSI 7-Ebene der Anwendungsschicht, was heutzutage in jeder Unternehmenssicherheit zum Standard wird. Tatsächlich verschleiert WebSockets die Übertragung und kann daher einen schwerwiegenden Verstoß gegen das Sicherheitsleck darstellen.

Arnaud Bouchez
quelle
2
@ArnaudBouchez - +1 für die schöne Ausstellung auf CDN. Schnelle Folgefrage - Was halten Sie von der Machbarkeit von Event Delivery-Netzwerken? Gemustert nach CDNs, aber darauf ausgerichtet, Streaming-Daten usw. über Websockets oder eine andere, noch nicht sichtbare Technologie zu liefern.
Quixver
8

Stellen Sie sich das so vor: Was ist billiger, eine offene Verbindung aufrechtzuerhalten oder für jede Anforderung eine neue Verbindung zu eröffnen (denken Sie daran, dass es sich bei dem Verhandlungsaufwand um TCP handelt).

Natürlich hängt es von der Anwendung ab, aber für langfristige Echtzeitverbindungen (z. B. einen AJAX-Chat) ist es weitaus besser, die Verbindung offen zu halten.

Die maximale Anzahl von Verbindungen wird durch die maximale Anzahl von freien Ports für die Sockets begrenzt.

kaoD
quelle
Sie können die Verbindung ohne Verwendung eines WebSocket offen halten (dank der Keep-Alive-Option von HTTP / 1.1). Ich bin mir nicht sicher, ob ich Ihren Standpunkt hier verstehe.
Arnaud Bouchez
1
+1. Die Leute neigen dazu zu vergessen, dass das Einrichten einer TCP-Verbindung eine Synchronisierung / Bestätigung / Bestätigung erfordert und TLS mehr Roundtrips für den Schlüsselaustausch erfordert.
Quixver
1
@ArnaudBouchez check en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets sind so lange geöffnet, wie Sie möchten, und nicht hackisch (wie Long-Polling und andere Alternativen).
kaoD
-5

Nein, es skaliert nicht, es gibt enorme Arbeit für Zwischenroutenschalter. Auf der Serverseite erreichen die Seitenfehler (Sie müssen alle diese Deskriptoren behalten) hohe Werte, und die Zeit, um eine Ressource in den Arbeitsbereich zu bringen, nimmt zu. Dies sind meistens von JAVA geschriebene Server, und es ist möglicherweise schneller, diese Unmengen von Sockets festzuhalten, als einen zu zerstören / zu erstellen. Wenn Sie einen solchen Server auf einem Computer ausführen, kann sich kein anderer Prozess mehr bewegen.

user2195463
quelle