【发布时间】:2018-04-22 17:56:57
【问题描述】:
我们的服务器每天在特定时间段内向外扩展 1-3 个实例。我们有 Azure Redis 背板用于信号器的连接持久性。除此之外,服务器没有启用 ARR Affinity。顺便说一句,我们在 Android 上使用 ServerSentEvents,在 iOS 上使用 WebSocket。
问题是我们的移动用户(摩托车快递员)在移动信号低时经常断开或重新连接到 SignalR 服务器,因为他们的提供商。
我们已经通过移动端检查了所有内容。我们很确定我们一次只有一个信号器连接。除此之外,当它们连接时,我们将它们的连接 ID 存储在持久存储(SQL 数据库)中。
在向用户发送消息时,我们选择存储在数据库中的最新连接 ID。这意味着我们只向客户端发送了唯一的一个连接 id。
但是,我们收到一些关于我们通过服务器发送的消息在他们的手机上弹出两次的反馈(大多数情况下,消息在服务器有 2 或 3 个实例的高峰时间收到两次)。
我们无法追查为什么会收到两次,尤其是在高峰时段。
问题是,这是否与 ARR Affinity 有关?因为 Redis 背板使用订阅和发布方法,并且由于快递员经常断开/重新连接,他们有机会连接不同的服务器,因此,当服务器发送消息时,2 个服务器可能会尝试发送该消息,并且它会在他们的手机上弹出两次即使他们只有一个连接。
附加信息;
SignalR DisconnectTimeOut = 60 秒
SignalR KeepAlive = 20 秒
【问题讨论】:
-
解决此类问题的唯一真正方法是在您的消息中引入 id 和 acks。这就是您保证没有重复项的方式(通过让客户检查 id)。至于为什么会这样,很难知道。我认为亲和力不会影响 SignalR 2.x,因为消息仍然通过背板
-
好吧,既然消息都来了~同时,这两条消息都触发了调用事件。我需要为每条消息锁定/解锁。为什么我怀疑 ARR 是我们每次都会点击同一个实例,以便 SignalR 每次断开/重新连接时都会连接到同一个实例
标签: android azure redis signalr