WebSockets verwenden

Diese Seite enthält Anleitungen und Best Practices zum Ausführen von WebSockets oder anderen Streamingdiensten in Cloud Run und zum Schreiben von Clients für solche Dienste.

WebSockets werden in Cloud Run unterstützt, ohne dass eine zusätzliche Konfiguration erforderlich ist. WebSockets-Streams sind jedoch HTTP-Anfragen, die dem für Ihren Cloud Run-Dienst konfigurierten Zeitlimit für Anfragen unterliegen. Sie müssen also sicherstellen, dass diese Einstellung für Ihre Nutzung von WebSockets wie das Implementieren von Neuverbindungen in Ihren Clients gut funktioniert.

Selbst wenn Sie die Sitzungsaffinität in Cloud Run verwenden, die die Best-Effort-Affinität bietet, können WebSockets-Anfragen aufgrund des integrierten Load-Balancing möglicherweise trotzdem an verschiedenen Instanzen enden. Zur Behebung dieses Problems müssen Sie die Daten zwischen Instanzen synchronisieren.

Beachten Sie, dass WebSockets in Cloud Run auch unterstützt werden, wenn Sie Cloud Load Balancing verwenden.

WebSockets-Beispieldienst bereitstellen

Verwenden Sie Cloud Shell, um auf schnelle Weise einen Beispiel-Whiteboard-Dienst bereitzustellen, der WebSockets mit Cloud Run verwendet: Beispiel bereitstellen

Wenn Sie diesen Beispiel-Whiteboard-Dienst manuell bereitstellen möchten, gehen Sie so vor:

  1. Klonen Sie das Socket.IO-Repository lokal mit dem Git-Befehlszeilentool:

    git clone https://github.com/socketio/socket.io.git
    
  2. Gehen Sie zum Beispielverzeichnis:

    cd socket.io/examples/whiteboard/
    
  3. Erstellen Sie einen neuen Cloud Run-Dienst, indem Sie den Dienst mithilfe der Google Cloud CLI aus dem Quellcode erstellen:

    gcloud run deploy whiteboard --allow-unauthenticated --source=.
    
  4. Nachdem der Dienst bereitgestellt wurde, öffnen Sie zwei separate Browsertabs und rufen Sie die Dienst-URL auf. Alles, was Sie auf einem Tab zeichnen, sollte an den anderen Tab weitergegeben werden (und umgekehrt), da die Clients über WebSockets mit derselben Instanz verbunden sind.

WebSockets-Chat – Vollständige Anleitung

Wenn Sie eine vollständige Codeanleitung benötigen, finden Sie im Thema WebSocket-Chatdienst für Cloud Run erstellen zusätzliche Codebeispiele.

Best Practices

Der schwierigste Teil der Erstellung von WebSockets-Diensten in Cloud Run ist das Synchronisieren von Daten zwischen mehreren Cloud Run-Instanzen. Dies ist aufgrund des Autoscalings und der zustandslosen Toleranz für Instanzen und aufgrund der Limits für Gleichzeitigkeit und Zeitlimits für Anfragen schwierig.

Umgang mit Anfrage-Zeitüberschreitungen und Client-Neuverbindungen

WebSockets-Anfragen werden in Cloud Run als lange laufende HTTP-Anfragen behandelt. Sie unterliegen Zeitüberschreitungen für Anfragen (derzeit bis zu 60 Minuten und standardmäßig 5 Minuten), auch wenn Ihr Anwendungsserver keine Zeitüberschreitungen erzwingt.

Entsprechend wird die Clientverbindung getrennt, wenn der Client die Verbindung länger als die erforderliche Zeitüberschreitung, die für den Cloud Run-Dienst konfiguriert ist, offen lässt und das Zeitlimit der Anfrage überschritten wird.

Daher sollten WebSockets-Clients, die eine Verbindung zu Cloud Run herstellen, die Verbindung zum Server wiederherstellen, wenn es zu einer Zeitüberschreitung der Anfrage kommt oder die Verbindung zum Server getrennt wird. Dies erreichen Sie in browserbasierten Clients mit Bibliotheken wie reconnecting-websocket oder durch eine Verarbeitung von "Trennungs"-Ereignissen, wenn Sie die SocketIO Bibliothek nutzen.

Abrechnung bei der Verwendung von WebSockets

Eine Cloud Run-Instanz mit einer beliebigen offenen WebSocket-Verbindung gilt als aktiv, sodass die CPU zugewiesen und in Rechnung gestellt wird.

Gleichzeitigkeit maximieren

WebSocket-Dienste sind in der Regel für die gleichzeitige Verarbeitung vieler Verbindungen konzipiert. Da Cloud Run gleichzeitige Verbindungen (bis zu 1000 pro Container) unterstützt, empfiehlt Google, die maximale Gleichzeitigkeitseinstellung für Ihren Container auf einen höheren Wert als der Standardwert, wenn Ihr Dienst die Last mit bestimmten Ressourcen verarbeiten kann.

Sticky Sessions (Sitzungsaffinität)

Da WebSockets-Verbindungen zustandsorientiert sind, bleibt der Client während der gesamten Verbindung mit demselben Container in Cloud Run verbunden. Dies bietet eine natürliche Haltbarkeit im Kontext einer einzelnen WebSocket-Verbindung.

Bei mehreren und nachfolgenden WebSockets-Verbindungen können Sie Ihren Cloud Run-Dienst so konfigurieren, dass er die Sitzungsaffinität verwendet. Dies bietet jedoch eine Best-Effort-Affinität, sodass WebSockets Anfragen dennoch von verschiedenen Instanzen erhalten werden. Clients, die eine Verbindung zu Ihrem Cloud Run-Dienst herstellen, werden möglicherweise von verschiedenen Instanzen bedient, die keine Daten koordinieren oder freigeben.

Zur Umgehung dieses Problems verwenden Sie einen externen Datenspeicher, um den Status zwischen Cloud Run-Instanzen zu synchronisieren. Dies wird im nächsten Abschnitt erläutert.

Daten zwischen Instanzen synchronisieren

Sie müssen Daten synchronisieren, damit Clients, die eine Verbindung zu einem Cloud Run-Dienst herstellen, dieselben Daten über die WebSockets-Verbindung erhalten.

Beispiel: Angenommen Sie erstellen einen Chatroom-Dienst mit WebSockets und setzen die Einstellung maximale Gleichzeitigkeit auf 1000. Wenn mehr als 1000 Nutzer gleichzeitig eine Verbindung zu diesem Dienst herstellen, werden sie von unterschiedlichen Instanzen bereitgestellt. Die Nutzer können daher nicht die gleichen Nachrichten im Chatroom sehen.

Zum Synchronisieren von Daten zwischen Ihren Cloud Run-Instanzen, z. B. für den Empfang von Nachrichten, die in allen Instanzen in einem Chatroom gepostet wurden, benötigen Sie ein externes Datenspeichersystem, z. B. eine Datenbank oder eine Nachrichtenwarteschlange.

Wenn Sie eine externe Datenbank wie Cloud SQL verwenden, können Sie regelmäßig Nachrichten an die Datenbank senden und die Datenbank abfragen. Beachten Sie jedoch, dass Cloud Run-Instanzen keine CPU haben, wenn der Container keine Anfragen verarbeitet. Wenn Ihr Dienst hauptsächlich WebSockets-Anfragen verarbeitet, wird dem Container so lange CPU zugewiesen, wie mindestens ein Client mit ihm verbunden ist.

Nachrichtenwarteschlangen verbessern die Datensynchronisierung zwischen Cloud Run-Containern in Echtzeit, da die externen Nachrichtenwarteschlangen nicht jede Instanz adressieren können, um Daten per Push zu übertragen. Ihre Dienste müssen neue Nachrichten aus der Nachrichtenwarteschlange per Pull abrufen, indem sie eine Verbindung zur Nachrichtenwarteschlange herstellen.

Google empfiehlt die Verwendung externer Warteschlangensysteme für Nachrichten wie: Redis Pub/Sub (Memorystore) oder Echtzeit-Updates in Firestore, die Updates an alle Instanzen über Verbindungen senden können, die von der Containerinstanz initiiert werden.

Redis Pub/Sub verwenden

WebSocket-Chatroom-Dienstarchitektur

Um den Redis-Pub/Sub-Mechanismus nutzen zu können, müssen Sie eine Redis-Instanz aus dem Memorystore erstellen. Wenn Sie die Socket.IO-Bibliothek für WebSockets verwenden, können Sie deren Redis-Adapter einsetzen.

In dieser Redis-basierten Architektur stellt jede Cloud Run-Instanz eine lange Verbindung mit dem Redis-Kanal her, der die empfangenen Nachrichten enthält (durch den Befehl SUBSCRIBE). Sobald die Containerinstanzen eine neue Nachricht auf dem Kanal erhalten, können sie diese in Echtzeit über ihre WebSockets an ihre Clients senden.

Wenn ein Client eine Nachricht mit WebSockets ausgibt, veröffentlicht die Instanz, die die Nachricht empfängt, die Nachricht (mit dem Befehl PUBLISH) im Redis-Kanal und andere Instanzen, die diesen Kanal abonniert haben, erhalten diese Nachricht.

Wenn Sie eine vollständige Codeanleitung benötigen, finden Sie im Thema WebSocket-Chatdienst für Cloud Run erstellen zusätzliche Codebeispiele.