Was sind die Gefahren bei der Verwendung von Websockets anstelle von RESTful HTTP?

76

Ich arbeite derzeit an einem Projekt, bei dem der Client einen großen Auftrag anfordern und an den Server senden muss. Anschließend teilt der Server den Job auf und antwortet mit einer Reihe von URLs, damit der Client einen GET-Aufruf tätigt und die Daten zurückstreamen kann. Ich bin das Greenhorn des Projekts und verwende derzeit Spring-Websockets, um die Effizienz zu verbessern. Anstatt dass die Clients ständig einen Ping-Befehl an den Server senden, um festzustellen, ob die Ergebnisse zum Streamen bereit sind, wird der Websocket jetzt direkt mit dem Client Kontakt aufnehmen.

Wäre es eine schlechte Idee, wenn Websockets den gesamten Prozess von Ende zu Ende verwalten? Ich verwende STOMP mit Spring-Websockets. Wird es immer noch große Probleme mit dem Auslassen von REST geben?

geschmuggelte Pfannkuchen
quelle

Antworten:

124

Mit RESTful HTTP verfügen Sie über ein zustandsloses Anforderungs- / Antwortsystem, bei dem der Client eine Anforderung sendet und der Server die Antwort zurückgibt.

Mit webSockets verfügen Sie über ein statusbehaftetes (oder möglicherweise zustandsbehaftetes) Nachrichtenübermittlungssystem, bei dem Nachrichten in beide Richtungen gesendet werden können und das Senden einer Nachricht einen geringeren Overhead hat als bei einer RESTful-HTTP-Anforderung / Antwort.

Die beiden sind ziemlich unterschiedliche Strukturen mit unterschiedlichen Stärken.

Die Hauptvorteile eines verbundenen webSocket sind:

  1. Zwei-Wege-Kommunikation. So kann der Server den Client jederzeit über alles informieren. Anstatt einen Server in regelmäßigen Abständen abzufragen, um festzustellen, ob etwas Neues vorhanden ist, kann ein Client ein webSocket einrichten und einfach auf Nachrichten vom Server warten. Aus Sicht des Servers sendet der Server einfach eine Nachricht an den Client, wenn ein für einen Client interessantes Ereignis auftritt. Der Server kann dies nicht mit einfachem HTTP tun.

  2. Geringerer Overhead pro Nachricht. Wenn Sie erwarten, dass viel Verkehr zwischen Client und Server fließt, ist der Overhead pro Nachricht mit einem webSocket geringer. Dies liegt daran, dass die TCP-Verbindung bereits hergestellt ist und Sie nur eine Nachricht an einen bereits geöffneten Socket senden müssen. Bei einer HTTP-REST-Anforderung müssen Sie zuerst eine TCP-Verbindung herstellen, die zwischen Client und Server mehrere Hin- und Herbewegungen umfasst. Anschließend senden Sie eine HTTP-Anfrage, empfangen die Antwort und schließen die TCP-Verbindung. Die HTTP-Anforderung enthält notwendigerweise einen gewissen Overhead, z. B. alle Cookies, die auf diesen Server ausgerichtet sind, auch wenn diese für die jeweilige Anforderung nicht relevant sind. HTTP / 2 (neueste HTTP-Spezifikation) ermöglicht diesbezüglich eine zusätzliche Effizienz, wenn es sowohl vom Client als auch vom Server verwendet wird, da eine einzelne TCP-Verbindung für mehr als nur eine einzelne Anforderung / Antwort verwendet werden kann.

  3. Höhere Skalierung unter bestimmten Umständen. Bei geringerem Overhead pro Nachricht und ohne Client-Abfrage, um festzustellen, ob etwas neu ist, kann dies zu einer zusätzlichen Skalierbarkeit führen (höhere Anzahl von Clients, die ein bestimmter Server bedienen kann). Die Skalierbarkeit von webSocket hat auch Nachteile (siehe unten).

  4. Stateful Verbindungen. Ohne auf Cookies und Sitzungs-IDs zurückgreifen zu müssen, können Sie den Status für eine bestimmte Verbindung direkt in Ihrem Programm speichern. Während mit zustandslosen Verbindungen viel entwickelt wurde, um die meisten Probleme zu lösen, ist es mit zustandsbehafteten Verbindungen manchmal einfacher.

Die Hauptvorteile einer RESTful HTTP-Anforderung / Antwort sind:

  1. Universelle Unterstützung. Es ist schwer, allgemeiner unterstützt zu werden als HTTP. Obwohl webSockets derzeit relativ gut unterstützt werden, gibt es unter bestimmten Umständen immer noch keine regelmäßige Unterstützung für webSocket.

  2. Kompatibel mit mehr Serverumgebungen. Es gibt Serverumgebungen, in denen Serverprozesse mit langer Laufzeit nicht zulässig sind (einige Situationen mit gemeinsamem Hosting). Diese Umgebungen können HTTP-Anforderungen unterstützen, jedoch keine lang laufenden webSocket-Verbindungen.

  3. Höhere Skalierung unter bestimmten Umständen. Die webSocket-Anforderung für einen kontinuierlich verbundenen TCP-Socket fügt der Serverinfrastruktur einige neue Skalierungsanforderungen hinzu, die HTTP-Anforderungen nicht erfordern. Dies ist also ein Kompromissraum. Wenn die Vorteile von webSockets nicht wirklich benötigt werden oder in erheblichem Umfang genutzt werden, können HTTP-Anforderungen möglicherweise besser skaliert werden. Es hängt definitiv vom spezifischen Nutzungsprofil ab.

  4. Bei einer einmaligen Anforderung / Antwort ist eine einzelne HTTP-Anforderung effizienter als das Einrichten eines webSocket, dessen Verwendung und anschließendes Schließen. Dies liegt daran, dass das Öffnen eines webSocket mit einer HTTP-Anforderung / Antwort beginnt. Nachdem beide Seiten ein Upgrade auf eine webSocket-Verbindung vereinbart haben, kann die eigentliche webSocket-Nachricht gesendet werden.

  5. Staatenlos. Wenn Ihre Arbeit nicht durch eine zustandslose Infrastruktur komplizierter wird, kann eine zustandslose Welt die Skalierung oder das Failover erheblich vereinfachen (fügen Sie einfach Serverprozesse hinter einem Load Balancer hinzu oder entfernen Sie sie).

  6. Automatisch zwischenspeicherbar. Mit den richtigen Servereinstellungen können http-Antworten vom Browser oder von Proxys zwischengespeichert werden. Es gibt keinen solchen integrierten Mechanismus für Anforderungen, die über webSockets gesendet werden.


Um die Art und Weise anzusprechen, wie Sie die Frage gestellt haben:

Was sind die Gefahren bei der Verwendung von Websockets anstelle von RESTful HTTP?

  1. In großem Maßstab (Hunderttausende von Clients) müssen Sie möglicherweise einige spezielle Serverarbeiten ausführen, um eine große Anzahl gleichzeitig verbundener webSockets zu unterstützen.

  2. Alle möglichen Clients oder Toolsets unterstützen keine webSockets oder über sie gestellten Anforderungen auf derselben Ebene, auf der sie HTTP-Anforderungen unterstützen.

  3. Einige der kostengünstigeren Serverumgebungen unterstützen nicht die lang laufenden Serverprozesse, die zur Unterstützung von webSockets erforderlich sind.

Wenn es für Ihre Anwendung wichtig ist, Fortschrittsbenachrichtigungen an den Client zurückzusenden, können Sie entweder eine lange laufende http-Verbindung verwenden, während der fortlaufende Fortschritt gesendet wird, oder Sie können ein webSocket verwenden. Das webSocket ist wahrscheinlich einfacher. Wenn Sie das webSocket wirklich nur für die relativ kurze Dauer dieser bestimmten Aktivität benötigen, finden Sie möglicherweise die besten Kompromisse, wenn Sie ein webSocket nur für die Zeitdauer verwenden, in der Sie Daten an den Client und senden können Verwenden Sie dann http-Anforderungen für die normalen Anforderungs- / Antwortaktivitäten.

jfriend00
quelle
1
Danke für die ausführliche Antwort. Ich warte immer noch auf dieses magische Framework, das Websockets de facto zum Erstellen von Webanwendungen macht. Mir gefällt sehr gut, was Spring mit Websockets macht. Vielleicht entwickelt es sich später zu etwas Großem.
geschmuggelt
Warum erwähnt niemand, dass REST-Antworten zwischengespeichert werden können und es keine einfache / automatische Möglichkeit gibt, das Ergebnis von Websocket zwischenzuspeichern?
Metamaker
1
@metamaker - Das ist ein vernünftiger Punkt und ich werde ihn hinzufügen. WebSocket-Verbindungen werden jedoch normalerweise nicht für Anforderungs- / Antwortaktivitäten verwendet, bei denen das Caching relevant ist, und tatsächlich ist http normalerweise die empfohlene Wahl für reine Anforderungen / Antworten.
jfriend00
@ jfriend00 Genau, aber dies ist definitiv ein Anwendungsfall, da REST im Vergleich zu WebSockets glänzt.
Metamaker
Auf der Support-Seite sind wir fast zu 100% für Browser: caniuse.com/#feat=websockets
Rexcirus
3

Es hängt wirklich von Ihren Anforderungen ab. REST-Services können im Vergleich zu Websockets viel transparenter und für Entwickler einfacher abzurufen sein.

Mit Websockets entfernen Sie die meisten Vorteile, die RESTful-Webservices bieten, z. B. die Möglichkeit, eine Ressource über einen URI zu referenzieren. Was Sie wirklich tun sollten, ist herauszufinden, welche Vorteile REST und Hypermedia haben, und auf dieser Grundlage zu entscheiden, ob diese Vorteile für Sie wichtig sind.

Es ist natürlich durchaus möglich, einen RESTful-Webservice zu erstellen und ihn mit einer Websocket-basierten API für Echtzeitantworten zu erweitern.

Wenn Sie jedoch einen Dienst erstellen, den nur Sie in einer kontrollierten Umgebung nutzen werden, besteht der einzige Nachteil möglicherweise darin, dass nicht jeder Client Websockets unterstützt, während so gut wie jede Art von Umgebung einen einfachen http-Aufruf ausführen kann.

Evert
quelle
Mit Spring-Websockets und Spring-Messaging kann ich ein / @ MessageMapping durchführen, um URIs zu haben. Ich kann auch einen Spring-mvc / @ RequestMapping-Aufruf ausführen! Es scheint, als könnten Spring-Websockets RESTful wie Abstraktionen ermöglichen? Hier verliere ich mich, wahrscheinlich weil ich naiv bin, aber dadurch wirkt die Entwicklung von Websockets wirklich attraktiv, aber ich höre nicht viel darüber.
geschmuggelt