多数据库同步 - SignalR与消息背板

ksp*_*rin 7 architecture asp.net scalability signalr

问题

我的申请表如下:

  • 多个(<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将同步消息(包含所有需要的同步数据)推送到所有连接的客户端设备(用于与数据相关的位置).

下图说明了此解决方案:

提出的解决方案

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

问题

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

您也欢迎并赞赏您对此解决方案的一般意见和建议.

Cha*_*ith 3

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

  • 使用 Web 套接字本身并不实用,因此有一些流行的库,例如SignalR、socket.io。这些库吸收了生产和开发中面临的许多困难。这些库甚至支持缩放。
  • 由于您的堆栈是基于 .net 的,因此此处选择 SignalR。
  • SignalR 在大多数情况下都能很好地工作。在这里,您不必担心背板成为实时游戏中的瓶颈。

但维护 SignalR 等自托管实时解决方案是有成本的。在现有的 SignalR 中,通信的成功率并不高可靠,您将不得不实施各种监控机制和故障转移过程。也不支持地理分布。因此,解决所有提及问题的高可靠实时系统的下一个选择是托管服务,例如pub-nub