如何在分布式系统中维护套接字或通信通道

how sockets or communication channels are maintained in distibuted system

我是分布式系统的新手,有一次需要将 gRPC 服务部署到 kubernetes (GKE) 时遇到了这个问题。据我所知,当客户端启动 rpc 时,它会创建一个持久的 http2 连接,并在其上多路复用进一步的调用。我喜欢通过此连接向客户端发送 send/push 通知或类似消息。如果我部署到多个 pod,则连接分布在它们之间,并且不确定找到通道注册到客户端的实例的最佳方法是什么。一个可能的解决方案是,一旦用户启动连接,就在集中式服务中保留 clientId 和 pod ip(或某些标识)的引用,其他 pods 查找 pod 并将消息转发给它。类似的东西是可取的还是有现成的解决方案?我对此不熟悉 space,非常感谢任何建议。

编辑:(对@mebius99 的回复)

在查看部署选项时,我偶然发现了 GKE,而其他云部署选项因我使用 gRPC/http2 而受到限制。感谢您提到 service discovery ,或者 service mesh 可能是一个选项。使用 gRPC,客户端维护与单个 pod 的长期连接。所以,我希望每个 pod 都能够基于唯一的 clientId(客户端可以进行初始注册 rpc 调用)来查询它连接的是哪个 pod,因此可以利用此连接以及一种 pods 的方式来转发它们之间的消息。所以,就像当我收到来自客户端的注册呼叫时,我更新了关于客户端和 pod ip 的中央注册表,然后从任何 pod 中查找它并将包转发给它,以便它通过现有的流连接进一步转发给客户端。你指引我走向正确的方向,请让我知道以上在容器环境中是可能的。

谢谢。

听起来您想实现某种发布-订阅系统。

你必须先做一些规模的粗略计算,比如有多少客户端,每秒多少消息。

然后你可以选择是自己实现还是选择现成的系统,比如https://doc.akka.io/docs/alpakka/current/google-cloud-pub-sub-grpc.html

另一个想法,你可以使用 Envoy 代理。
如果您使用的是 GKE,这些帖子会很有帮助。

我建议从 Kubernetes Service concept and Service discovery. The External HTTP(S) Load Balancing 开始应该适合您的需要。

如果您需要更复杂的东西,Envoy proxy + Network Load Balancing could be a solution, as is 在这里。

我只是想在这里对现有的答案进行更多的解释。

由于 HTTP/2 中的请求是多路复用的(多个请求可以在任何时间点在同一连接上处于活动状态),请求将只固定到单个 Kubernetes pod。因此,我们需要配置服务网格以从基于连接的平衡转变为基于请求的平衡。提到的 Envoy Proxy 就是一个例子。

我推荐大家阅读这篇来自 Kubernetes 博客的好文章 https://kubernetes.io/blog/2018/11/07/grpc-load-balancing-on-kubernetes-without-tears