【问题标题】:SignalR combined with load balancer missing messagesSignalR 结合负载均衡器丢失消息
【发布时间】:2018-04-10 23:13:10
【问题描述】:

我在硬件防火墙后面有 2 个 Web 服务器 (IIS 8.5),我们的应用程序使用 SignalR 进行一些实时更新。我们使用 SQL Server 作为背板来帮助我们在这个负载平衡的环境中工作。此外,我们在负载均衡器上使用粘性会话来帮助我们在会话期间将用户保持在同一 Web 服务器上。当我们在这种硬件配置中运行时,我们会丢失至少 1/3 的消息。有时我们会收到所有预期的信息,但更多时候我们会错过很多信息。

当我们在单个 Web 服务器上运行时,所有消息都会被接收。有人对解决此问题有任何建议吗?我们已经打开了日志(客户端和服务器),看起来没有任何东西丢失或损坏。我们真的很难过。

编辑---

我希望能提供一些额外的细节来说明情况。

  • 服务器到客户端的消息正在丢失。几乎我们所有的通信都是服务器到客户端。
  • 我们正在使用仅基于 IP 的粘性会话,并且限制为 5 分钟,但我们会在 5 分钟内丢失消息。
  • 这是一些旧的 SignalR 代码,自 SignalR 1(甚至更早版本)以来,它只被最低限度地触及。 我们在内存中保留了用户列表及其连接,我们使用该列表将通知发送回客户端。这似乎很可能是问题的原因,但使用粘性会话用户应该至少在同一台服务器上停留 5 分钟,对吧?
  • 此用户列表将用户名映射到连接 ID。当我们的后端服务(在另一台机器上)使用用户名而不是连接 ID 发送回消息时,这很有用。

【问题讨论】:

  • 您能否尝试将此用户列表保存在分布式内存中,如果不是为了好,至少可以缩小问题范围。由于您已经拥有用于 signalr 的 sql server,您可以在 sql server 中支持您的会话,如果列表不太大,则将列表保留在那里。或者,您可以考虑使用像 memcached 或 redis 这样的分布式缓存(或者如果太多,那么只需存储在您自己的数据库表中)

标签: websocket signalr load-balancing signalr-backplane signalr-2


【解决方案1】:

在两台服务器的 web.config 中指定相同的 machineKey

【讨论】:

  • 已经完成。它没有什么不同。在我们之前的环境中,我们使用 ARR 作为负载均衡器,并且必须进行更改。以前的环境现在与硬件负载平衡器更加一致,我们看到始终丢弃消息。
  • @Steven 我在硬件负载平衡器后面使用 Signalr,也带有 sql 背板。我也在使用粘性会话。丢失的消息是客户端到客户端、客户端到服务器还是服务器到客户端?
  • 我用一些额外的细节更新了这个问题。
【解决方案2】:

终于解决了这个问题。真的有2个问题。首先是我们在上面的编辑中使用了内存中的用户列表。一旦我们意识到这不会跨机器工作,我们就将其删除。这也将我们引向了第二个问题,即 SignalR 2 如何使用 IUserIdProvider 而我们的调用应该是

Clients.User(userId).send(message)

而不是

context.Clients.Client(connection)

自从我们多年前第一次开始使用 SignalR 以来,此代码就已经存在,并且随着我们升级 SignalR 版本而从未正确更新

【讨论】:

  • 谢谢,我刚刚做了。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-14
  • 2018-02-01
相关资源
最近更新 更多