【发布时间】:2018-07-29 10:30:30
【问题描述】:
在构建分布式系统时,必须确保客户端和服务器最终以一致的视图结束它们正在操作的数据,即它们永远不会不同步。需要格外小心,因为网络不能被认为是可靠的。也就是说,在网络故障的情况下,客户端永远不知道操作是否成功,可能会决定重试调用。
考虑一个微服务,它公开了简单的 CRUD API 和无限的客户端集,由同一团队、不同团队和不同公司在内部维护。
在示例中,客户端请求创建新实体,微服务成功创建并持久化该实体,但网络失败,客户端连接超时。客户端很可能会重试,在不知情的情况下第二次持久化同一个实体。这是我想出的一种可能的解决方案:
- 使用客户端生成的标识符来防止重复发布
这可能意味着主键,客户端和服务器生成的组合键的一半,或服务发布的令牌。如果具有该标识符的实体已经存在,则服务将保留该实体,或者回复 OK 消息。
但还有更多:如果客户端在网络故障后放弃(但实体被持久化),改变它对实体的内部视图,然后决定将其持久化到具有相同 id 的服务中。在这一点上,一般来说,静默服务是否合理:
- 更新具有客户发布状态的现有实体
或者服务应该用一些更具体的状态代码来回答发生了什么?关键是,服务的开发者并不能真正影响客户端的设计解决方案。
那么,有哪些明智的做法可以在分布式系统中保持状态一致并避免网络和系统故障时最常见的陷阱?
【问题讨论】:
-
我不理解用例“将现有实体分配给客户发布的实体”。你能给我更多的细节或帮助我理解吗?
-
嗯,这只是意味着删除旧实体(如果存在),并插入新的客户发布。旧的和新的具有相同的主键。或者,服务器可以回答实体已经存在(因为它确实存在),但它的状态与客户端发布的状态不同
-
但是服务器为什么要删除旧实体呢?为什么不让它保持这种状态,当客户端更新它时,它们会同步。
-
是的,基本上是一样的
-
服务器不知道客户端知道什么,所以除非客户端请求,否则它不应该做任何事情。
标签: rest web-services architecture microservices distributed-computing