我一直在阅读一些关于最终一致性和编排微服务的文章和问题,但我还没有看到这个问题的明确答案。我会用通俗易懂的术语来表达。
简单地说,:如果客户端对系统进行后续的同步REST调用,那么一旦调用到不同的微服务(由于最终的一致性),当后面的调用可能返回意外的结果时,您会做什么?
问题
假设您有一个提供REST的单块应用程序。假设有两个模块A和B要转换为微服务。B维护的实体可以指A维护的实体(例如A维护学生和B维护班级)。在单片环境中,模块只是引用同一个数据库,但在微服务情况下,每个模块都有自己的数据库,并通过异步消息进行通信。所以他们的数据库最终是一致的。
我们API的一些现有第三方客户端应用程序用于首先(同步)调用属于模块A的端点,在第一次调用返回之后,立即(即几毫秒后)调用模块B中的端点作为其工作流程的一部分(例如创建一个学生并将其放入类中)。在新的情况下,这会导致一个问题:当第二个调用发生时,模块B可能还不知道模块A中的变化。因此,客户端应用程序的现有工作流可能会中断。(例如,B模块可能会回答:你想要进入课堂的学生并不存在,或者是在错误的一年。)
当人工用户通过某些前端应用程序单独进行调用时,这并不是什么大问题,因为模块通常在第二次调用之后是一致的。当客户端应用程序(不受我们控制)只调用A,然后立即调用B作为自动化工作流的一部分时,问题就出现了。在这种情况下,最终的一致性是不够快的。
问题
是否有最佳做法或普遍商定的一套备选方案来缓解这一问题?(我编出了学生/班级的例子,不要对这方面的细节感到困惑。:)
我们能想到什么
有没有更好的方法?哪一个最合适?
编辑:澄清了这个问题主要是关于第三方客户端自动调用端点的行为,这意味着即使是几毫秒的延迟在最终的一致性中也可能是致命的。
发布于 2021-03-29 09:59:16
这个问题以一致性为中心的解决方案是基于分布式事务的,这带来了很高的复杂性和性能方面的影响。
在围绕monolith到微服务迁移的这精彩文章中,扎马克·德哈尼也谈到了数据的不一致性:
众所周知,分布式事务难以实现,因此,微服务体系结构强调服务之间的无事务协调,并明确认识到一致性可能只是最终的一致性,并通过补偿操作来解决问题。
因此,在基于微服务的体系结构中,最终一致性是唯一的数据一致性选项,如果您需要强大的一致性保证,那么您需要构建工作周围(补偿操作),比如重试流程,这将增加额外的复杂性。
此外,本文还强调了一种非常有洞察力的方法来查看与业务工作流有关的数据不一致:
对许多开发团队来说,选择以这种方式管理不一致是一个新的挑战,但它往往与业务实践相匹配。企业通常会处理一定程度的不一致,以便快速响应需求,同时有某种逆转过程来处理错误。,在更大的一致性下,只要修复错误的成本小于失去业务的成本,就值得进行权衡。
下面是我对这个问题的看法:
发布于 2021-03-30 20:17:52
是否有最佳做法或普遍商定的一套备选方案来缓解这一问题?
是。您不能用自己的存储库将每个方法分解成自己的微服务。
您可以对您的微服务和存储库进行调整,以适应真正的一致性要求。如果您有一个用例,在调用服务端点A之后紧接着调用服务端点B,它需要查看第一个调用的结果,那么A和B应该是同一个微服务的一部分,或者共享相同的存储库。
https://stackoverflow.com/questions/65217718
复制相似问题