【发布时间】:2018-03-23 18:37:15
【问题描述】:
我有一个客户端/服务器架构,客户端在连接时执行以下操作:
- 打开到服务器的套接字并请求更改流(“流”)。
- 从服务器获取所有数据(“快照”)。
所以这里的想法是快照将在连接点获取客户端所有相关数据,并且流将继续发送更改 - 这样客户端就不必一遍又一遍地进行轮询和获取快照.
这样做的问题是快照和流启动之间存在间隙,这可能导致数据丢失。示例:
- 客户端从服务器请求快照和流。
- 服务器从数据库中获取快照。
- 另一个客户端提交了对 db 的更改(因此快照已过时)。更改将发送到所有流。
- 客户端的流已启动。
正如您在上面看到的,客户端最终得到一个过时的快照,并且由于流 init 是异步的,它可能会错过对数据库的更改(它永远不会看到第 3 步中的更改)。
我对如何解决这个问题有一些想法,但到目前为止我对其中任何一个都不满意:
1) 先初始化流,然后获取快照。我不相信这个是安全的,因为这假设流服务器(rabbitmq/kafka/pulsar)不会错过传输中的消息。 2) 让流也推送在连接时间前最后 X 秒内所做的更改。这不是很好,因为它对概率进行时间假设和赌注。
感谢所有输入!
【问题讨论】:
-
在服务器端可以做什么?例如,您能否枚举更改并让快照包含上次更改的 ID,以便您可以查看是否缺少任何更改并请求?
-
@md2perpe 这实际上是我最终要做的。如何以一种好的方式做到这一点并不明显(仍然没有尝试过),但似乎在更新实体通过流之后使用更新消息的流 id 更新它们似乎是一个万无一失的解决方案到这个。
标签: database asynchronous synchronization client-server message-queue