Websocket 客户端通过负载平衡器后面的多信号服务器进行管理

Websocket 客户端通过负载平衡器后面的多信号服务器进行管理,websocket,signalr,scaling,Websocket,Signalr,Scaling,假设我有两台股票行情服务器,它们将报价推送到web浏览器客户端。这两台服务器位于负载平衡器后面(循环模式)。 考虑下面的场景: 客户端A在服务器1上订阅Google股票,如下所示:Groups.Add(Context.ConnectionId,“Google”) 客户端B在Server2上订阅雅虎股票:Groups.Add(Context.ConnectionId,“Yahoo”) 客户端C在服务器2上订阅谷歌股票:Groups.Add(Context.ConnectionId,“谷歌”) 现在

假设我有两台股票行情服务器,它们将报价推送到web浏览器客户端。这两台服务器位于负载平衡器后面(循环模式)。 考虑下面的场景:

  • 客户端A在服务器1上订阅Google股票,如下所示:
    Groups.Add(Context.ConnectionId,“Google”)

  • 客户端B在Server2上订阅雅虎股票:
    Groups.Add(Context.ConnectionId,“Yahoo”)

  • 客户端C在服务器2上订阅谷歌股票:
    Groups.Add(Context.ConnectionId,“谷歌”)

  • 现在这两个服务器都已经与股市同步,所以当股票更新时,它们都会实时更新

    我的问题是:

    当server2按如下方式推送新更新时:

    Clients.Group("Google").tick(quote);
    
    它将向哪些客户发送消息?它将永远是客户端C吗?我想不是,我们中间有一个负载平衡器,所以在给定时间连接的客户端可能会改变,对吗?它现在可能是C,但下一步可以是客户端A&C或仅A。web套接字的连接假定保持打开状态,那么负载平衡器将如何处理该连接,它是否总是将连接从一个客户端转发到特定的服务器

    背板在这里对我没有帮助,因为我的两台服务器已经同步,将同时发送相同的消息。因此,如果我强制他们通过背板将消息路由到另一台服务器,那么最终会向客户端发送重复消息,如下所示:

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

    服务器1向其客户端发送2个Google Ticker
    服务器2向他的客户端发送2个Google Ticker,好的,最终我通过共享缓存(Redis)同步了所有组订阅,这样所有服务器都知道所有用户及其子订阅。这样,每台服务器都将知道其当前的客户机注册组,并将推送相关数据

    更新:

    经过深思熟虑,我们终于做到了:

  • 负载平衡器将为传入连接分配一个粘性会话,以便每个新连接都有一个恒定的信号服务器
  • 第1节将使Redis同步冗余,因为每个服务器都知道其所有客户端
  • 如果服务器\网络出现故障,则SignalR客户端将重新连接,并由负载平衡器为其分配一个新的(如果服务器出现故障)服务器
  • 重新连接后,Signal客户端将重新订阅相关库存(如果故障发生在网络上,负载平衡器将其重定向到旧的Signal服务器,则可能是多余的,但我会接受)

  • 这是最糟糕的。最好不要进行负载平衡,而是重定向到“免费”服务器。不需要连接到动态切换服务器。Tom,你能解释一下重定向到“免费”服务器是什么意思吗?为什么负载平衡在这里被认为是一种不好的做法呢?因为它会给状态分布带来问题。最好是让服务器连接到一个已知的(负载平衡的)点,该点为他分配一个CMM通信服务器并发出http重定向。无负载平衡器(成本),无状态同步(成本)。服务器崩溃?重新连接,转到其他服务器。