要旨
我有一个在基于微服务的架构(在 Kubernetes 上)上运行的应用程序。与应用程序外部的所有通信都通过 发生API网关 .
这只是意味着来自我前端的请求不会直接发送到服务,但它们必须通过网关。
动机
现在我需要实现一个需要在前端和内部服务之间进行实时通信的功能。但是由于内部服务没有对外公开,我需要一种通过网关“路由”实时数据的方法。
我所有的服务都在 Node.js 上运行,这就是我想使用 Socket.IO 的原因实现实时通信。
问题
但是如何从草图中实现紫色双箭头?
所以通常前端客户端会连接到运行 Socket.IO 的服务器。但在我的情况下,这个服务器(实时功能服务器)不能从客户端访问(并且永远不应该),这意味着客户端必须连接到网关。因此网关需要实现某种机制来将所有传入消息路由到实时服务,反之亦然。
想法
(1) 让第二个 HTTP 服务器监听网关上的事件并将这些事件发送到实时服务器。在另一个方向,实时服务器将事件发送到网关,网关然后将它们发送到前端。我认为这种方法肯定会奏效,但是将所有内容发出两次似乎是多余的。它肯定会损害性能?
(2) 将 Socket.IO Adapter 用于“pass event between nodes”,这似乎是正确的方法,因为它用于“在进程或计算机之间传递消息”。但是由于缺乏文档/示例,我在入门时遇到了问题。我也没有使用 Redis(是否需要使用适配器?)
(3) 使用 socket.io-emitter包,这似乎不是一个好选择,因为上次提交是在 3 年前。
(4) 还有什么?
最佳答案
好吧,基本上我是这样设计的应用程序
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: centsideas-ingress
annotations:
kubernetes.io/tls-acme: 'true'
kubernetes.io/ingress.class: 'nginx'
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- centsideas.com
- api.centsideas.com
secretName: centsideas-tls
rules:
- host: api.centsideas.com
http:
paths:
- path: /socker.io
backend:
serviceName: socket-service
servicePort: 8000
- path: /
backend:
serviceName: centsideas-gateway
servicePort: 3000
- host: centsideas.com
http:
paths:
- backend:
serviceName: centsideas-client
servicePort: 8080
服务
apiVersion: v1
kind: Service
metadata:
name: socket-service
annotations:
service.beta.kubernetes.io/external-traffic: "OnlyLocal"
namespace: namespace
spec:
sessionAffinity: ClientIP
ports:
- name: ws-port
protocol: TCP
port: 8000
type: ClusterIP
selector:
service: ws-api
然后创建部署以部署 ws-service。像这样,您也可以激活 k8s HPA(水平 pod 自动缩放)来扩展 socket.io 服务。
您必须根据您的 k8s 版本更改注释和其他选项(我认为注释
service.beta.kubernetes.io/external-traffic: "OnlyLocal"
已被弃用)。
关于node.js - SocketIO 与客户端和服务之间的网关通信?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61382439/