Kern
Ich habe eine Anwendung, die auf einer Microservice-basierten Architektur (auf Kubernetes) ausgeführt wird. Die gesamte Kommunikation zu / von außerhalb der Anwendung erfolgt über eine API-Gateway .
Das bedeutet nur, dass Anfragen von meinem Frontend nicht direkt an die Dienste gehen, sondern über das Gateway.
Motiv
Jetzt muss ich eine Funktion implementieren, die eine Echtzeitkommunikation zwischen dem Frontend und einem internen Dienst erfordert. Da der interne Dienst jedoch nicht nach außen ausgerichtet ist, muss die Echtzeitdaten über das Gateway "weitergeleitet" werden.
Alle meine Dienste werden auf Node.js ausgeführt. Aus diesem Grund möchte ich Socket.IO verwenden , um die Echtzeitkommunikation zu implementieren.
Problem
Aber wie implementiert man den lila Doppelpfeil aus der Skizze?
Normalerweise stellt der Frontend-Client eine Verbindung zu dem Server her, auf dem Socket.IO ausgeführt wird. In meinem Fall ist dieser Server (der Echtzeit-Feature-Server) vom Client aus nicht zugänglich (und sollte es auch nie sein), was bedeutet, dass der Client eine Verbindung zum Gateway herstellen muss. Daher muss das Gateway einen Mechanismus implementieren, um alle eingehenden Nachrichten an den Echtzeitdienst und umgekehrt zu leiten.
Ideen
(1) Lassen Sie einen zweiten HTTP-Server auf Ereignisse auf dem Gateway warten und senden Sie diese Ereignisse an den Echtzeitserver. In der anderen Richtung sendet der Echtzeitserver Ereignisse an das Gateway, die sie dann an das Frontend senden. Ich denke, dieser Ansatz wird definitiv funktionieren, aber es scheint überflüssig, alles zweimal zu emittieren. Und es würde definitiv die Leistung beeinträchtigen?
(2) Verwenden Sie einen Socket.IO-Adapter, um " Ereignisse zwischen Knoten zu übergeben ". Dies scheint der richtige Weg zu sein, da er zum "Übergeben von Nachrichten zwischen Prozessen oder Computern" verwendet wird. Ich habe jedoch Probleme beim Einstieg, da es an Dokumentation / Beispielen mangelt. Ich benutze auch kein Redis (wird der Adapter benötigt?)
(3) Verwenden Sie das Paket socket.io-emitter , das seit dem letzten Commit vor 3 Jahren keine gute Option zu sein scheint.
(4) Noch etwas?
quelle
ingress-controller
k8s wird diesocket
Datenverkehr an den Fußballdienst .nginx
als Ingress-Controller gemacht. Sie können auch Haproxy verwenden, wenn Sie es vorziehen. Sie haben 2 Dienste (Bereitstellung), 1 zum Verwalten von HTTP-Anforderungen und 1 zum Verwalten von Socket-Anforderungen. Mit ingress können Sie den Pfad verfügbar machen und den Datenverkehr an den richtigen Dienst/socket
umleiten, z. B. jede Anforderung, an die ein Treffer weitergeleitet wirdsocket-service
Anwendung .Antworten:
Okay, im Grunde habe ich die Anwendung so gestaltet
Ingress
Bedienung
Anschließend erstellen Sie Ihre Bereitstellung, um den ws-Dienst bereitzustellen. Auf diese Weise können Sie auch k8s HPA (horizontale Pod-Autoskalierung) aktivieren, um den Dienst socket.io zu skalieren. Sie müssen Anmerkungen und andere Optionen basierend auf Ihrer k8s-Version ändern (ich denke, die Anmerkung
service.beta.kubernetes.io/external-traffic: "OnlyLocal"
ist veraltet).quelle
socket-service
hinzufügen und ihn dem Ingress hinzufügen?Da der interne Dienst nicht nach außen gerichtet ist, empfehle ich die Verwendung eines Tunnels. ngrok ist ein Befehl für eine sofortige und sichere URL zu Ihrem localhost-Server über ein beliebiges NAT oder eine Firewall. Wenn Ihr Server den Socket-Dienst über einen bestimmten Port verfügbar macht, verwenden Sie verfügbar macht , erstellen Sie ngrok einen Reverse-Proxy, um die Welt verfügbar zu machen, mit der Sie eine Verbindung zu Ihrer Frontend-Anwendung herstellen können. Die Verwendung dieses Befehls ist sehr einfach. Hier ist ein Beispiel für die Verwendung:
Führen Sie einfach die folgende Anweisung aus, damit es funktioniert
./ngrok http 3000
Um es dauerhaft zu machen, müssen Sie einen Dienst erstellen und eine Datei ngrok.yml für die beste Konfiguration verwenden.
Hier ist die offizielle Dokumentation hier
quelle