socket.io 在多个服务器上 w/o redis

socket.io over multiple servers w/o redis

我的 api 端点分布在多个位置的多个服务器上,我正在尝试弄清楚如何处理连接的客户端上的套接字更新。 我真的很想避免只设置一个 redis 数据库来处理许多服务器上连接的客户端。

我不必广播消息,套接字消息将始终发送给单个用户。 虽然我知道每个连接的客户端通道 ID,但我不确定当我手上只有通道 ID 时是否可以只向单个用户发送消息,例如初始连接是与其中一个集群中的另一台服务器建立的.

我看到 sticky load balancing 有一个选项,但我不完全确定那是我真正需要的。

感谢所有能给我更深入解释的最佳方法的人。

不太清楚你在问什么。当您让用户连接到各种服务器并且您想要从一个服务器向特定用户发送消息时,您必须最终将该消息传递到用户连接到的服务器,以便它可以通过用户的服务器发送消息联系。

有多种方法可以做到这一点:

  1. 中央数据库。维护一个中央数据库,告诉您用户在任何给定时间连接到哪个服务器。然后,当您想向用户 A 发送消息时,您可以在中央数据库中查找他们,发现他们当前已连接到 Server12,然后您可以要求 Server12 向他们发送消息。这是 socket.io redis 解决方案使用的策略。此策略可能会在中央数据库中造成瓶颈,因为所有服务器都必须使用相同的中央数据库来 "lookup" 给定用户连接的地方。

  2. 负载均衡算法。创建一个负载平衡算法,根据给定用户的用户 ID 计算给定用户将连接到哪个服务器(通常使用用户 ID 的散列,然后它在当前活动的服务器数量之间平均分配)。在此方案中,当用户连接时,他们将负载平衡到算法选择的服务器。因此,例如,userA 将始终被发送到 Server12。然后,在您的服务器场的其他地方,如果您想向用户 A 发送消息,您可以使用相同的算法来计算他们将连接到哪个服务器,并可以联系该服务器以请求它向他们发送消息。当您想要更改活动服务器的数量时,此方案可能会遇到困难,因为这会导致负载平衡算法发生变化,这需要所有现有用户通过新算法重新连接以再次建立连接 predictable。

  3. 向所有服务器广播出站消息。向所有服务器广播特定用户的出站消息。在这种情况下,如果 Server10 想要向用户 A 发送消息,它首先检查是否已经有用户 A 的连接。如果是,它只是发送消息。如果没有,则它只是向所有其他活动服务器广播它要将此特定消息发送给 UserA。每个服务器将检查其连接列表,如果它有 UserA 的连接,它将向 UserA 发送消息。此方法不能很好地适应高流量(例如,由于所有服务器都接收所有出站消息而导致大量消息的情况),但可以很好地适应大量用户,但流量较低。

  4. 每个服务器维护自己的连接索引, 向所有服务器广播传入连接和断开连接。在这个方案中,每个服务器都为任何连接的用户维护一个内存索引。每当用户连接到特定服务器时,该服务器就会向所有其他服务器广播用户 A 现在连接到 Server12。每当 UserA 断开连接时,断开连接也会被广播。每个服务器都会在每个事件上更新它的内存索引,因此在任何给定时刻,每个服务器都可以实时查找 table 每个用户当前连接的位置。这种方法不适用于大量用户,因为每台服务器的任务是保留所有活动连接的内存索引,并且当任何用户连接或断开连接时,每台服务器都会收到一条消息。但是,它确实适用于高流量,因为每台服务器都已经有一种快速的方法来了解给定用户的连接位置。

根据您尝试优化的给定情况的特定负载特征,您也可以将这些方法中的每一种方法的各个方面组合成混合解决方案。例如,连接和断开连接可以广播到 N 个专用数据库服务器,然后各个服务器可以在查找给定用户的连接位置时将负载分散到这 N 个数据库服务器上,以减轻中央数据库的瓶颈。