使用消息队列扩展WebSockets



我已经构建了一个WebSockets服务器,它充当聊天消息路由器(即接收来自客户端的消息,并根据客户端ID将其推送给其他客户端)。

要求服务能够扩展以处理数百万个并发的开放套接字连接,我希望能够水平扩展服务器。

我想到的体系结构是将websocket服务器节点放在负载均衡器后面,这会产生问题,因为连接到不同节点的客户端不会相互了解。当客户端AB都通过LoadBalancer进入时,客户端A可能与节点1有开放连接,而客户端B连接到节点2——每个节点都有自己的开放套接字连接字典。

为了解决这个问题,我考虑使用一些MQ系统,如ZeroMQRabbitMQ。所有websocket服务器节点都将是MQ服务器的订阅者,当节点收到将消息路由到不在本地连接字典中的客户端的请求时,它将pub-lish向MQ服务器发送一条消息,MQ服务器将告诉所有sub描述符节点查找该客户端,并在该客户端连接到该节点时发出该消息。

Q1:这种体系结构有意义吗?

Q2:这里描述的pub-sub模式真的是我想要的吗?

ZeroMQ将是我的选择-无论是架构方面还是;性能方面

--快速&低延迟(可以衡量您的实现性能和开销,低至子级别)

--无代理(不引入另一个故障点,而其本身可以具有{N+1|N+M}自修复架构)

--smart准备使用的正式通信模式基元(PUB/SUB是最不重要的基元)

--公平队列&负载平衡架构内置(外部观察者不可见)

--许多用于服务器端内部多进程/多线程分布式/并行处理的传输类

--准备几乎线性可扩展性

自适应节点重新发现

这是一个比较复杂的问题。您想要创建一个可行的体系结构,必须深入了解更多细节才能解决。

  • 节点身份验证与对等消息
  • 节点(重新)-发现与法律&隐私问题
  • 基于节点的自主自组织代理与中央策略实施需求

为了在2021年更新这一点,我们刚刚解决了这个问题,我们需要设计一个能够处理来自物联网设备的数百万个同时WS连接的系统。WS服务器只是将消息中继到处理实际逻辑的无服务器API后端。我们选择使用docker和节点ws包,使用前面有ALB的自动缩放AWS ECS Fargate集群。

这解决了路由消息的主要问题,但随后我们遇到了同样的问题,即如何从服务器路由响应消息。我们最初只考虑保留一个连接的中央数据库,但将消息路由到ALB后面的特定Fargate实例似乎不可行。

相反,我们使用AWS SNS设置了一个简单的sub/pub模式(https://aws.amazon.com/pub-sub-messaging/)。每个WS服务器接收响应,然后搜索其自己的WS连接。由于每个Fargate实例只处理路由(没有逻辑),所以当我们垂直扩展它们时,它们可以处理很多连接。

更新:为了提高性能,您可以使用Redis-Pub/Sub等持久连接,允许响应消息只发送到一台服务器,而不是每个服务器。

最新更新