使用负载均衡器后面的多 SignalR 服务器进行客户端管理



假设我有 2 个股票行情服务器将报价推送到 Web 浏览器客户端。 2 台服务器位于负载均衡器后面(循环模式)。请考虑以下方案:

  1. 客户端 A 在 Server1 上订阅谷歌股票,如下所示:Groups.Add(Context.ConnectionId, "Google");

  2. 客户端 B 在 Server2 上订阅雅虎股票:Groups.Add(Context.ConnectionId, "Yahoo");

  3. 客户端 C 在 Server2 上订阅谷歌股票:Groups.Add(Context.ConnectionId, "Google");

现在,两台服务器都已经与股票市场同步,因此当股票更新时,它们都会实时获得更新。

我的问题是:

当 Server2 推送如下新更新时:

Clients.Group("Google").tick(quote);

它将向其发送消息的客户端是谁?它将始终是客户端 C?我想不是,我们中间有一个负载均衡器,所以在给定时间连接的客户端可能会改变,对吧?它现在可能是C,但下一个勾选可以是客户端A&C或只有A。Web 套接字的连接假设保持打开状态,那么负载均衡器将如何处理,它是否总是将连接从 1 个客户端转发到特定服务器?

背板在这里对我没有帮助,因为我的 2 台服务器已经同步并且会同时发送相同的消息。 因此,如果我强迫他们通过背板将消息路由到另一台服务器,最终会像这样将重复的消息发送给客户端:

server1 在 10:00 将股票代码 X 发送到 Google -->路由到背板 -->路由到服务器 2server2 在 10:00 将代码 X 发送到 Google--> 路由到背板 -->路由到服务器 1

服务器 1 向他的客户发送 2 X Google 代码服务器 2 向他的客户发送 2 个 Google 代码

好的,最终我已经将所有组订阅同步到共享缓存(Redis)中,因此所有服务器都知道所有用户及其订阅。 这样,每个服务器将知道他当前的客户端注册的组,并将推送相关数据。

更新:

经过深思熟虑,这就是我们最终所做的:

  1. 负载均衡器会将粘性会话分配给传入连接,以便每个新连接都有一个常量 SignalR 服务器。
  2. 第 1 节将使 Redis 同步变得冗余,因为每个服务器都知道他的所有客户端。
  3. 如果服务器\网络出现故障,SignalR 客户端将重新连接,并由负载均衡器分配新的(如果服务器出现故障)服务器。
  4. 重新连接后,SignalR 客户端将重新订阅相关股票(如果故障发生在网络上并且负载均衡器将其重定向到旧的 SignalR 服务器,则可能是多余的,但我会接受这一点)。

最新更新