多数据库同步 - 带消息传递背板的SignalR

时间:2015-05-25 02:06:08

标签: asp.net architecture signalr scalability

问题

我的申请表如下:

  • 多个(< 20)设备客户端(Android)在一个位置运行。
  • 存在数千个位置(因此存在数十或数十万个设备客户端)。
  • 还存在一个门户网站客户端,它与每个位置的数据及其设备客户端同步工作。
  • 设备上生成的新数据通过REST API(ASP.net WebAPI)发布到服务器(云)。

到目前为止,该应用程序是一个非常标准的应用程序,具有移动设备客户端和Web门户客户端。

但是,由于每个设备客户端的要求不受我的控制(设备客户端需要在脱机模式下运行,减少网络延迟等),每个设备客户端都不使用服务器数据库作为其直接记录源。每个设备客户端都有自己的本地数据库(SQLite),该数据库与其所在位置的所有数据保持同步。例如:当我在设备客户端A上进行数据更改时,需要将该更改传播到设备客户端B和Web门户客户端C.

  • Web门户客户端直接从服务器数据库读取,因为它不需要脱机功能。

正如您所看到的,问题在于我们现在需要一种方法来保持所有设备客户端数据库彼此实时同步。预计两个设备客户端之间的数据短暂延迟并被认为是正常的。

提议的解决方案

我建议的解决方案如下:

  • 当新客户端设备最初联机时,它会收到自上次从服务器通过REST API上线以来错过的数据转储。
  • 通过REST API从客户端设备发布/更新/删除的每个新数据项都会传播到服务器数据库。服务器数据库包含所有位置的所有数据,应被视为永久记录源。
  • Web门户直接与服务器数据库一起工作,因为它没有脱机类型要求。
  • 通过SignalR建立与每个客户端设备的连接到数据同步流服务。
  • 工人服务是"拖尾"用于新建/更新/删除操作的服务器数据库。检测到CUD操作时,会为每个数据同步服务实例将消息分派到Azure Service Bus队列/订阅(通过扇出主题)。这允许SignalR数据同步服务(使用Azure Service Bus背板)的水平扩展,因为将存在数千个设备客户端连接。
  • 数据同步服务从其消息队列/订阅中读取,并通过SignalR将同步消息(包含同步所需的所有数据)推送到所有连接的客户端设备(与数据相关的位置)。

下图说明了此解决方案:

Proposed solution

  • 大块描述服务器(灰色方块是可以水平扩展的HTTP Web服务器)
  • 箭头描述了流经应用程序的数据的方向。

问题

  1. SignalR是解决此问题/解决方案的正确技术吗?最初我的解决方案涉及每个客户端设备建立自己的Azure Service Bus队列/订阅,该队列/订阅从数据库尾部工作者(sync river)收集消息。该解决方案的问题在于,如果有的话,我会将大量浪费的消息推送到离线设备客户端,这些客户端可能不会在很长一段时间内重新联机。通过在设备客户端最初联机时转储增量数据,然后通过SignalR传输数据,我可以解决这个问题。
  2. 之前我没有在生产环境中广泛使用SignalR,所以我对它有点新意。对于这个解决方案,我可以期待遇到哪些问题/挑战?
  3. 以下article指出"在某些情况下,背板可能成为瓶颈。以下是一些典型的SignalR场景:高频实时(例如,实时游戏):不建议在这种情况下使用背板。"。这个解决方案会属于这一类吗? Azure Service Bus消息的背板会引入哪些问题?如果不是这样,我还能如何扩展这个解决方案?
  4. 您也欢迎并赞赏您对此解决方案的一般意见和建议。

1 个答案:

答案 0 :(得分:3)

您需要在设备上线时与设备进行实时通信。最有希望的方法之一是使用Web套接字。

  • 使用网络套接字本身并不实用,因此很受欢迎 它的库,如 SignalR,socket.io 。这些库吸收 生产和发展中面临许多困难。这些 图书馆甚至支持扩展。
  • 由于您的堆栈基于.net,因此选择SignalR。
  • SignalR在大多数情况下都能正常工作。在这里你不必 担心背板成为实时发生的瓶颈 游戏。

但是维持一个自我托管的实时解决方案,如SignalR,需要付出代价。 SignalR的通信成功率不高,您必须实施各种监控机制和故障转移流程。地理分布也不受支持。因此,解决所有提及问题的高可靠性实时系统的下一个选择是托管服务,例如 pub-nub