我构建了一个WebSockets
服务器,充当聊天消息路由器(即从客户端接收消息并根据客户端ID
将其推送到其他客户端)。
要求服务能够扩展以处理数百万个并发的开放套接字连接,并且我希望能够水平扩展服务器。
我想到的架构是将websocket服务器节点放在负载均衡器后面,这会产生问题,因为连接到不同节点的客户端不会彼此了解。虽然客户A
和B
都通过LoadBalancer
输入,但客户端A
可能与节点1
建立了开放式连接,而客户端B
已连接到节点2
- 每个节点都拥有它自己的开放套接字连接字典。
为了解决这个问题,我考虑使用一些MQ系统,如ZeroMQ
或RabbitMQ
。所有websocket服务器节点都将是MQ服务器的订户,当节点收到将消息路由到不在本地连接字典中的客户端的请求时,它将 pub
- 向MQ服务器发送一条消息,告知所有 sub
-scriber节点查找此客户端,并在该节点连接到该节点时发出消息。
Q1:
这种架构有意义吗?
Q2:
这里描述的 pub-sub
模式真的是我要找的吗?
答案 0 :(得分:13)
- 快速& 低延迟(可以衡量您的实施性能和开销,直至子[usec]规模)
- 无代理(不会引入另一个故障点,而本身可以有{N + 1 | N + M}自我修复架构)
- 智能准备使用的正式沟通模式原语( PUB
/ SUB
是最少的红衣主教一个)
- 公平队列&负载平衡体系结构内置(外部观察者不可见)
用于服务器端内部多进程/多线程分布式/并行处理的- 许多传输类
- 准备 几乎线性可扩展性
这是一个更复杂的主题。您打算创建可行的架构将需要深入了解更多细节以便解决。
答案 1 :(得分:1)
为了在 2021 年进行更新,我们刚刚解决了这个问题,我们需要设计一个系统来处理来自物联网设备的数百万个同步 WS 连接。 WS 服务器只是将消息中继到我们处理实际逻辑的无服务器 API 后端。我们选择使用 docker 和节点 ws
包,使用自动扩展的 AWS ECS Fargate 集群,其前面有一个 ALB。
这解决了路由消息的主要问题,但随后我们遇到了如何从服务器路由响应消息的相同问题。我们最初考虑只保留一个连接的中央数据库,但将消息路由到 ALB 后面的特定 Fargate 实例似乎不可行。
相反,我们使用 AWS SNS (https://aws.amazon.com/pub-sub-messaging/) 设置了一个简单的 sub/pub 模式。每个 WS 服务器接收响应,然后搜索自己的 WS 连接。由于每个 Fargate 实例仅处理路由(无逻辑),因此当我们垂直缩放它们时,它们可以处理大量连接。