【问题标题】:clients managment with multi SignalR servers behind a load balancer客户端管理与负载均衡器后面的多个 SignalR 服务器
【发布时间】:2016-01-15 13:19:10
【问题描述】:

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

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

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

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

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

我的问题是:

当 server2 像这样推送新的更新时:

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

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

背板在这里帮不了我,因为我的 2 个服务器已经同步并且会同时发送相同的消息。所以如果我强迫他们通过背板将他们的消息路由到另一台服务器,它最终会向客户端发送重复的消息,如下所示:

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

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

【问题讨论】:

    标签: websocket signalr scaling


    【解决方案1】:

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

    更新:

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

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

    【讨论】:

    • 这已经很糟糕了。最好不要进行负载平衡,而是重定向到“免费”服务器。无需连接即可动态切换服务器。
    • Tom,你能解释一下重定向到“免费”服务器是什么意思吗?为什么负载平衡在这里被认为是一种不好的做法?
    • 因为您在状态分布方面造成了问题。最好是让服务器连接到一个已知的(负载平衡的)点,该点为他分配一个通信服务器并发出一个 http 重定向。没有负载均衡器(成本),没有状态同步(成本)。服务器崩溃?重新连接,转到另一台服务器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 2017-05-15
    • 2015-04-10
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    相关资源
    最近更新 更多