问题
我的应用程序工作如下:
多个(<20)设备客户端(Android)正在一个位置运行。 数千个位置存在(因此存在数十或数十万个设备客户端)。 还存在一个Web门户客户端,它与每个位置的数据及其设备客户端同步工作。 在设备上生成的新数据通过REST API(ASP.net WebAPI)发布到服务器(云)。 到目前为止,这个应用程序是一个非常标准的移动设备客户端和Web门户客户端应用程序
但是,由于每个设备客户端的要求超出了我的控制范围(设备客户端需要以离线模式运行,减少网络延迟等),因此每个设备客户端都不会将服务器数据库用作其直接记录来源。 每个设备客户端都有自己的本地数据库(SQLite),该数据库与其位置的所有数据保持同步。 例如:当我在设备客户端A上进行数据更改时,需要将此更改传播到设备客户端B和Web门户客户端C.
Web门户客户端直接从服务器数据库中读取,因为它不需要脱机功能。 正如您所看到的,这里的问题是我们现在需要一种方法来实时保持所有设备客户端数据库彼此同步。 预计两台设备客户端之间数据同步的短暂延迟并被认为是可行的。
建议的解决方案
我提出的解决方案如下:
当新的客户端设备初次联机时,它会收到一个数据转储,以了解自上次从服务器通过REST API联机以来所丢失的内容。 通过REST API从客户端设备发布/更新/删除的每个新数据项都会传播到服务器数据库。 服务器数据库包含所有位置的所有数据,应被视为永久性记录来源。 Web门户直接与服务器数据库一起工作,因为它没有脱机类型要求。 来自每个客户端设备的连接通过SignalR建立到数据同步流服务。 一个辅助服务正在“拖拽”服务器数据库以进行新的创建/更新/删除操作。 当检测到CUD操作时,将为每个数据同步服务实例分派一条消息给Azure服务总线队列/订阅(通过扇出话题)。 这允许SignalR数据同步服务(使用Azure服务总线背板)进行水平缩放,因为将存在数千个设备客户端连接。 数据同步服务从其消息队列/预订读取,并通过SignalR将同步消息(包含同步所需的所有数据)推送到所有连接的客户端设备(与数据相关的位置)。 下图说明了此解决方案:
大块代表服务器(灰色方块是可以水平缩放的HTTP Web服务器) 箭头描绘了数据流经应用程序的方向。 问题
SignalR是这个问题/解决方案的正确技术吗? 最初,我的解决方案涉及每个客户端设备建立它自己的Azure服务总线队列/订阅,这些客户端设备收集来自数据库拖尾工作人员(sync river)的消息。 该解决方案的问题在于,我会将大量浪费的消息推送给离线设备客户端,因为这些客户端可能无法在很长一段时间内恢复在线状态。 当设备客户端最初联机并通过SignalR流数据后,通过倾销Delta数据,我可以解决这个问题。 我之前没有在生产环境中广泛使用过SignalR,所以我对它有点新意。 我可以期待在这个解决方案中遇到哪些问题/挑战? 以下文章指出:“有些情况下背板可能会成为瓶颈,下面是一些典型的SignalR场景:高频实时(例如实时游戏):不推荐在此场景中使用背板。” 这个解决方案是否属于这一类? Azure Service Bus消息传递的背板有什么问题? 如果不是这样,我还会如何扩展这个解决方案? 您对此解决方案的一般意见和建议也受到欢迎和赞赏。
您需要在设备联机时与设备进行实时通信。 最有前途的方法之一是使用网络套接字。
使用网络套接字本身并不实用,因此它有流行的库,如SignalR,socket.io。 这些库吸收了生产和开发中遇到的许多困难。 这些库甚至支持缩放。 由于您的堆栈是基于.net的SignalR,因此可以在此选择。 SignalR在大多数情况下都能正常工作。 在这里,您不必担心背板会成为实时游戏中的瓶颈。 但是维护SignalR等自主实时解决方案需要付出一定的代价。 库存SignalR的通信成功率不高,您将不得不实施各种监控机制和故障转移流程。 地理分布也不受支持。 因此,针对所有提及问题的高可靠性实时系统的下一个选择是托管服务,例如pub-nub。
链接地址:
http://www.djcxy.com/p/26477.html
上一篇:
SignalR with Messaging Backplane
下一篇:
How to use pipes(ioredirection) in Dockerfile RUN?