首先,您需要定义您要询问的问题的范围。如果您真正谈论的是动态水平扩展,其中您根据总负载启动和关闭服务器,那么这比仅仅确定将最新传入的新套接字连接路由到哪里是一个更复杂的问题。
为了解决这个问题,您必须有一种将套接字从一个主机“移动”到另一个主机的方法,这样您就可以清除来自您想要降速的主机的连接(我在这里假设真正的动态缩放会上升和上升)向下)。我见过的通常方法是让一个合作的客户端参与进来,你告诉客户端重新连接,当它重新连接时,它会负载平衡到另一台服务器上,这样你就可以清除你想要关闭的服务器。如果您的客户端已经具有自动重新连接逻辑(如 socket.io 那样),您可以让服务器关闭连接,客户端将自动重新连接。
至于对传入客户端连接进行负载平衡,您必须决定要使用的负载指标。最终,您需要为每个服务器进程打一个分数,告诉您您认为它有多“忙”,这样您就可以将新连接放在最不忙的服务器上。基本分数只是当前连接的数量。如果您的每个服务器进程有大量连接(数万个),并且在您的应用程序中没有特别的理由表明有些人可能比其他人更忙,那么大数定律可能会平均负载,这样您就可以侥幸逃脱每个服务器有多少连接。如果连接的使用不是那么公平甚至不公平,那么您可能还必须考虑 CPU 负载的某种时间移动平均值以及连接总数。
如果您要跨多个物理服务器进行负载平衡,那么您将需要每个人最初都连接到的负载平衡器或代理服务,并且该代理可以查看池中所有当前正在运行的服务器的指标并将连接分配给当前分数最低的一个。这可以通过代理方案或(更具可扩展性)通过重定向来完成,以便代理在初始分配后不碍事。
然后,您还可以有一个流程,定期检查集群中所有服务器上的负载分数(无论您决定计算它),并决定何时启动新服务器或何时关闭或何时停止运行。给定服务器上的平衡,并且需要告诉该服务器关闭多个连接,迫使它们重新平衡。
我不明白的是如何有效地将新的套接字连接路由到您选择的具有低套接字数的服务器。
如上所述,您可以使用代理方案或重定向方案。在连接时成本稍高,我更喜欢重定向方案,因为它在运行时更具可扩展性,并且为现有连接创建的故障点更少。所有客户端都连接到您的传入连接网关服务器,该服务器负责了解场中每个服务器的当前负载分数,并基于此将传入连接分配给得分最低的主机,然后重定向此新连接重新连接到场中的特定服务器之一。
我还看到了纯粹由自定义 DNS 实现完成的负载平衡。客户端请求 IP 地址farm.somedomain.com,该自定义 DNS 服务器为它们提供它希望分配给它们的主机的 IP 地址。查找 IP 地址的每个客户端farm.somedomain.com可能会获得不同的 IP 地址。您可以通过在自定义 DNS 服务器中添加或删除主机来启动或关闭主机,并且该自定义 DNS 服务器必须包含用于了解负载平衡逻辑和所有正在运行的主机的当前负载分数的逻辑。