在水平扩展的WebSocket服务器上负载平衡套接字?

spi*_*ce7 9 sockets websocket node.js vert.x perfect

每隔几个月,在考虑涉及套接字的个人项目时,我发现自己有一个问题:"如何在动态水平扩展的WebSocket服务器上正确加载平衡套接字?"

我理解水平扩展WebSockets并使用pub/sub模型将数据传递给保存特定用户的套接字连接的正确服务器的理论.我想我理解用最少的当前套接字连接有效识别服务器的方法,我也想要路由新的套接字连接.我不明白的是如何有效地将新套接字连接路由到您使用低套接字计数选择的服务器.

我不认为这个答案会与特定的服务器实现相关联,而是可以应用于大多数服务器.我很容易看到自己用vert.x,node.js甚至完美来实现它.

jfr*_*d00 9

首先,您需要定义您询问的问题的界限.如果你真的在谈论动态水平扩展,你可以根据总负载上下调整服务器,那么这只是一个问题,而不仅仅是找出路由最新传入的新套接字连接的位置.

要解决这个问题,你必须有一种方法可以将套接字从一个主机"移动"到另一个主机,这样你就可以清除你想要关闭的主机的连接(我假设真正的动态扩展同时发生了下).我见过这种方式的常用方法是通过与合作客户联系,告诉客户重新连接,重新连接时,将其负载平衡到不同的服务器上,这样您就可以清除想要关闭的服务器.如果您的客户端已经具有自动重新连接逻辑(如socket.io那样),您可以让服务器关闭连接,客户端将自动重新连接.

对于传入客户端连接的负载平衡,您必须确定要使用的负载指标.最终,您需要为每个服务器进程分数,告诉您您认为它是多么"繁忙",以便您可以在最不忙的服务器上建立新连接.最初的分数只是当前连接的数量.如果你的每个服务器进程有大量的连接(成千上万)并且你的应用程序中没有特别的原因,有些人可能比其他人忙得多,那么大数定律可能会平均负载所以你可以逃脱每个服务器有多少个连接.如果连接的使用不公平或不均匀,那么您可能还必须考虑CPU负载的某种时间移动平均值以及连接总数.

如果要在多个物理服务器之间进行负载均衡,那么您将需要一个每个人最初连接的负载均衡器或代理服务,该代理可以查看池中所有当前运行的服务器的度量标准,并将连接分配给目前得分最低的一个.这可以通过代理方案完成,也可以通过重定向实现(更具可伸缩性),这样代理就可以在初始分配后完成.

然后,您还可以在集群中的所有服务器上定期检查您的负载得分(但是您决定计算它),并决定何时启动新服务器或何时旋转一个服务器或者什么时候太远在给定服务器上的平衡,并且需要告知该服务器关闭多个连接,迫使它们重新平衡.

我不明白的是如何有效地将新套接字连接路由到您使用低套接字计数选择的服务器.

如上所述,您可以使用代理方案或重定向方案.在连接时成本略高,我赞成重定向方案,因为它在运行时更具可扩展性,并为现有连接创建更少的故障点.所有客户端都连接到您的传入连接网关服务器,该服务器负责了解服务器场中每个服务器的当前负载分数,并根据该服务器,它为具有最低分数的主机分配传入连接,然后重定向此新连接重新连接到服务器场中的某个特定服务器.


我还看到了纯粹由自定义DNS实现完成的负载均衡.客户端请求IP地址,farm.somedomain.com并且该自定义DNS服务器为它们提供了它希望分配给它的主机的IP地址.查找IP地址的每个客户端farm.somedomain.com可能会获得不同的IP地址.您可以通过在自定义DNS服务器中添加或删除主机来向上或向下旋转主机,并且该自定义DNS服务器必须包含用于了解负载平衡逻辑和所有正在运行的主机的当前负载分数的逻辑.

  • @spierce7 - 您可以使用代理模型或重定向模型。在代理模型中,它的工作原理就像NGINX做负载均衡一样。客户端连接到代理,然后代理连接到适当的主机并充当双向转发数据包的中间人。在这种情况下,我更喜欢重定向模型。客户端连接到负载均衡器,并将其重定向到新的 IP 地址,并建立新的连接。 (2认同)

Mat*_*att 5

将 websocket 请求路由到负载均衡器,负载均衡器决定将连接发送到何处。

例如,HAProxy有一种leastconn用于长连接的方法,该方法会选择最近最少使用且连接数最少的服务器。

HAProxy 后端服务器权重也可以通过外部输入进行修改,@jfriend00在其答案中详细介绍了权重的技术细节。