水平扩展的 WebSocket 服务器上的负载平衡套接字?
Load balancing sockets on a horizontally scaling WebSocket server?
每隔几个月,在思考一个涉及套接字的个人项目时,我发现自己会遇到 "How would you properly load balance sockets on a dynamic horizontally scaling WebSocket server?"
的问题
我了解水平扩展 WebSocket 和使用 pub/sub 模型将数据获取到为特定用户保存套接字连接的正确服务器背后的理论。我想我了解如何有效地识别当前套接字连接最少的服务器,我也想路由一个新的套接字连接。 我不明白的是如何有效地将新套接字连接路由到您选择的套接字数较少的服务器。
我不认为这个答案会与特定的服务器实现相关联,而是可以应用于大多数服务器。我可以很容易地看到自己用 vert.x、node.js 甚至完美实现了这一点。
首先,您需要定义所问问题的范围。如果您真正谈论的是根据总负载来启动和关闭服务器的动态水平缩放,那么这是一个比仅仅找出将最新传入的新套接字连接路由到何处更复杂的问题。
要解决这个问题,你必须有一种方法 "moving" 从一个主机到另一个主机的套接字,这样你就可以清除来自你想要降速的主机的连接(我在这里假设真正的动态缩放既可以向上也可以向下)。我见过的通常方法是让一个合作的客户端参与进来,你告诉客户端重新连接,当它重新连接时,它会负载平衡到另一台服务器上,这样你就可以清除你想要降速的服务器。如果您的客户端已经具有自动重新连接逻辑(如 socket.io 那样),您可以让服务器关闭连接,客户端将自动重新连接。
至于对传入客户端连接进行负载平衡,您必须决定要使用的负载指标。最终,您需要为每个服务器进程打分,告诉您 "busy" 您认为它如何,以便您可以在最不繁忙的服务器上建立新连接。基本分数只是当前连接数。如果每个服务器进程有大量连接(数万个),并且在您的应用程序中没有特别的原因表明某些连接可能比其他进程更忙,那么大数定律可能会平均负载,因此您可以逃脱每个服务器有多少个连接。如果连接的使用不是那么公平或均匀,那么您可能还必须考虑 CPU 负载的某种时间移动平均值以及连接总数。
如果您要在多个物理服务器之间进行负载平衡,那么您将需要每个人最初都连接到的负载平衡器或代理服务,并且该代理可以查看当前所有 运行 服务器的指标在池中并将连接分配给当前得分最低的连接。这可以通过代理方案或(更具可扩展性)通过重定向来完成,这样代理在初始分配后就不会挡路了。
然后您还可以有一个进程定期检查集群中所有服务器上的负载分数(无论您决定如何计算它),并决定何时启动新服务器或何时关闭一个服务器或何时启动新服务器给定服务器上的事情太不平衡了,需要告诉该服务器关闭多个连接,迫使它们重新平衡。
What I don't understand is how to effectively route new socket connections to the server you've picked with low socket count.
如上所述,您要么使用代理方案,要么使用重定向方案。连接时间的成本略高,我喜欢重定向方案,因为它在 运行 时更具可扩展性,并且为现有连接创建更少的故障点。所有客户端都连接到您的传入连接网关服务器,该服务器负责了解场中每个服务器的当前负载分数,并基于此将传入连接分配给得分最低的主机,然后重定向此新连接重新连接到您场中的特定服务器之一。
我还看到负载平衡完全由自定义 DNS 实现完成。客户端请求 farm.somedomain.com
的 IP 地址,该自定义 DNS 服务器为它们提供了它希望分配给它们的主机的 IP 地址。每个查找 farm.somedomain.com
的 IP 地址的客户端可能会得到不同的 IP 地址。您可以通过在自定义 DNS 服务器中添加或删除主机来向上或向下旋转主机,而自定义 DNS 服务器必须包含用于了解负载平衡逻辑和所有 运行 主机的当前负载分数的逻辑。
将 websocket 请求路由到负载均衡器,该负载均衡器决定将连接发送到哪里。
例如,HAProxy 有一个用于长连接的 leastconn
方法,它选择最近最少使用的连接数最少的服务器。
HAProxy 后端 server weightings can also be modified by external inputs, @jfriend00 detailed the technicalities of 。
我发现这个项目可能有用:
https://github.com/apundir/wsbalancer
描述中的一个片段:
Websocket balancer 是 websockets 的有状态反向代理。它在多个可用后端分发传入的 websocket。除了负载均衡之外,均衡器还负责在会话中出现异常故障时透明地从一个后端切换到另一个后端。
在此故障转移期间,远程客户端连接保持原样,因此远程客户端甚至看不到此故障转移。已尽一切努力确保 none 消息在此故障转移期间被丢弃。
关于您的问题:如果配置为这样做,新连接将由负载均衡器路由。
正如@Matt 提到的,例如使用 leastconn 选项的 HAProxy。
每隔几个月,在思考一个涉及套接字的个人项目时,我发现自己会遇到 "How would you properly load balance sockets on a dynamic horizontally scaling WebSocket server?"
的问题我了解水平扩展 WebSocket 和使用 pub/sub 模型将数据获取到为特定用户保存套接字连接的正确服务器背后的理论。我想我了解如何有效地识别当前套接字连接最少的服务器,我也想路由一个新的套接字连接。 我不明白的是如何有效地将新套接字连接路由到您选择的套接字数较少的服务器。
我不认为这个答案会与特定的服务器实现相关联,而是可以应用于大多数服务器。我可以很容易地看到自己用 vert.x、node.js 甚至完美实现了这一点。
首先,您需要定义所问问题的范围。如果您真正谈论的是根据总负载来启动和关闭服务器的动态水平缩放,那么这是一个比仅仅找出将最新传入的新套接字连接路由到何处更复杂的问题。
要解决这个问题,你必须有一种方法 "moving" 从一个主机到另一个主机的套接字,这样你就可以清除来自你想要降速的主机的连接(我在这里假设真正的动态缩放既可以向上也可以向下)。我见过的通常方法是让一个合作的客户端参与进来,你告诉客户端重新连接,当它重新连接时,它会负载平衡到另一台服务器上,这样你就可以清除你想要降速的服务器。如果您的客户端已经具有自动重新连接逻辑(如 socket.io 那样),您可以让服务器关闭连接,客户端将自动重新连接。
至于对传入客户端连接进行负载平衡,您必须决定要使用的负载指标。最终,您需要为每个服务器进程打分,告诉您 "busy" 您认为它如何,以便您可以在最不繁忙的服务器上建立新连接。基本分数只是当前连接数。如果每个服务器进程有大量连接(数万个),并且在您的应用程序中没有特别的原因表明某些连接可能比其他进程更忙,那么大数定律可能会平均负载,因此您可以逃脱每个服务器有多少个连接。如果连接的使用不是那么公平或均匀,那么您可能还必须考虑 CPU 负载的某种时间移动平均值以及连接总数。
如果您要在多个物理服务器之间进行负载平衡,那么您将需要每个人最初都连接到的负载平衡器或代理服务,并且该代理可以查看当前所有 运行 服务器的指标在池中并将连接分配给当前得分最低的连接。这可以通过代理方案或(更具可扩展性)通过重定向来完成,这样代理在初始分配后就不会挡路了。
然后您还可以有一个进程定期检查集群中所有服务器上的负载分数(无论您决定如何计算它),并决定何时启动新服务器或何时关闭一个服务器或何时启动新服务器给定服务器上的事情太不平衡了,需要告诉该服务器关闭多个连接,迫使它们重新平衡。
What I don't understand is how to effectively route new socket connections to the server you've picked with low socket count.
如上所述,您要么使用代理方案,要么使用重定向方案。连接时间的成本略高,我喜欢重定向方案,因为它在 运行 时更具可扩展性,并且为现有连接创建更少的故障点。所有客户端都连接到您的传入连接网关服务器,该服务器负责了解场中每个服务器的当前负载分数,并基于此将传入连接分配给得分最低的主机,然后重定向此新连接重新连接到您场中的特定服务器之一。
我还看到负载平衡完全由自定义 DNS 实现完成。客户端请求 farm.somedomain.com
的 IP 地址,该自定义 DNS 服务器为它们提供了它希望分配给它们的主机的 IP 地址。每个查找 farm.somedomain.com
的 IP 地址的客户端可能会得到不同的 IP 地址。您可以通过在自定义 DNS 服务器中添加或删除主机来向上或向下旋转主机,而自定义 DNS 服务器必须包含用于了解负载平衡逻辑和所有 运行 主机的当前负载分数的逻辑。
将 websocket 请求路由到负载均衡器,该负载均衡器决定将连接发送到哪里。
例如,HAProxy 有一个用于长连接的 leastconn
方法,它选择最近最少使用的连接数最少的服务器。
HAProxy 后端 server weightings can also be modified by external inputs, @jfriend00 detailed the technicalities of
我发现这个项目可能有用: https://github.com/apundir/wsbalancer
描述中的一个片段:
Websocket balancer 是 websockets 的有状态反向代理。它在多个可用后端分发传入的 websocket。除了负载均衡之外,均衡器还负责在会话中出现异常故障时透明地从一个后端切换到另一个后端。 在此故障转移期间,远程客户端连接保持原样,因此远程客户端甚至看不到此故障转移。已尽一切努力确保 none 消息在此故障转移期间被丢弃。
关于您的问题:如果配置为这样做,新连接将由负载均衡器路由。
正如@Matt 提到的,例如使用 leastconn 选项的 HAProxy。