我的api端点分布在多个位置的多个服务器上,我试图弄清楚如何处理连接客户端上的套接字更新。 我真的希望避免使用单个redis数据库设置来处理许多服务器上的连接客户端。
我不必广播消息,套接字消息将始终发送给单个用户。 虽然我知道每个连接的客户端通道id我不确定当我手上有通道ID时,它是否可能只向单个用户发出消息,例如初始连接是与其中一个集群中的另一个服务器建立的
我看到sticky load balancing有一个选项,但我不完全确定这是我真正需要的。
感谢所有能给我更深入解释最新方法的人。答案 0 :(得分:4)
目前尚不清楚你究竟在问什么。当您将用户连接到各种服务器并且您希望将消息从一个服务器发送给特定用户时,您必须最终将该消息传递给用户所连接的服务器,以便它可以通过用户发送消息连接。
有多种方法可以做到这一点:
中央数据库。维护一个中央数据库,告诉您在任何给定时间用户连接的服务器。然后,当您想要向userA发送消息时,您可以在中央数据库中查找它们并发现它们当前已连接到Server12,然后您可以要求Server12将消息发送给它们。这是socket.io redis解决方案使用的策略。此策略可能会在中央数据库中造成瓶颈,因为所有服务器必须使用相同的中央数据库来“查找”给定用户所连接的位置。
负载均衡算法。创建一个负载平衡算法,根据用户ID计算给定用户将连接到哪个服务器(通常使用userID的哈希值,然后在当前活动的服务器数量中均匀分配)。在该方案中,当用户连接时,它们被负载平衡到算法选择的服务器。因此,例如,userA将始终发送到Server12。然后,在服务器场的其他位置,如果要向userA发送消息,则可以使用相同的算法来计算它们将连接到哪个服务器,并且可以联系该服务器以请求它将消息发送给它们。当您想要更改活动服务器的数量时,此方案可能会遇到困难,因为这会导致负载平衡算法发生变化,这需要所有现有用户通过新算法重新连接,以使其连接再次可预测。
向所有服务器广播出站邮件。将特定用户的外发邮件广播到所有服务器。在这种情况下,如果Server10想要向userA发送消息,它首先检查它是否已经有userA的连接。如果是,它只是发送消息。如果没有,则它只向所有其他活动服务器广播它要将此特定消息发送给UserA。每个服务器将检查其连接列表,如果它具有UserA的连接,它将向UserA发送消息。此方法无法很好地适应高流量(例如,因为所有服务器都接收到所有出站消息而有大量消息的情况),但是对于大量用户而言可以很好地扩展,但是流量很低。
每个服务器维护自己的连接索引:广播所有服务器的传入连接和断开连接。在此方案中,每个服务器都为任何连接的用户维护内存索引。每当用户连接到特定服务器时,该服务器就会向UserA现在连接到Server12的所有其他服务器广播。每当UserA断开连接时,也会广播断开连接。每个服务器在每个事件上更新它的内存索引,因此在任何给定时刻,每个服务器都有一个实时查找表,其中包含每个用户当前连接的位置。此方法也不适用于大量用户,因为每个服务器的任务都是保留所有活动连接的内存索引,并且每个服务器在任何用户连接或断开连接时都会收到消息。但是,它确实适用于高流量,因为每个服务器都有一种快速了解给定用户连接位置的方法。
根据您尝试优化的特定情况的特定负载特征,可以将这些方法中的每一个的方面组合到混合解决方案中。例如,连接和断开连接可以广播到N个专用数据库服务器,然后各个服务器可以在查找给定用户连接的位置时将这些负载分散到这N个数据库服务器上,从而减轻中央数据库的负担。< / p>