我读过一篇文章说:
我们无法在分布式环境中的微服务中实现传统的事务系统,如 2 阶段提交。
我完全同意这一点。
但是,如果这里有人可以解释其确切原因,那就太好了。如果我使用微服务实现两阶段提交,我将面临哪些问题?
提前致谢
我读过一篇文章说:
我们无法在分布式环境中的微服务中实现传统的事务系统,如 2 阶段提交。
我完全同意这一点。
但是,如果这里有人可以解释其确切原因,那就太好了。如果我使用微服务实现两阶段提交,我将面临哪些问题?
提前致谢
避免两阶段提交的主要原因是事务协调器是一种独裁者,因为它告诉所有其他节点该做什么。通常事务协调器嵌入在应用程序服务器中。当事务协调器或应用程序服务器在第一阶段或准备阶段之后发生故障时,就会出现问题。现在,参与节点不知道该做什么。他们不能提交,因为他们不知道其他人是否对协调员回答了“否”,并且他们不能回滚,因为其他人可能对协调员说“是”。因此,直到协调器在 15 分钟(例如)后回来并完成第二阶段,参与的数据存储将保持锁定状态。这会抑制可扩展性和性能. 当协调者的事务日志在第一阶段后被破坏时,会发生更糟糕的事情。在这种情况下,数据存储将永远保持锁定状态。即使重新启动进程也无济于事。唯一的解决方案是手动检查数据以确保一致性,然后解除锁定。这些事情通常发生在高压情况下,因此绝对是一个巨大的运营开销。因此,传统的两阶段提交并不是一个好的解决方案。
但是,这里应该注意的是,一些现代系统,如 Kafka,也实现了 2 阶段提交。但这与传统解决方案的不同之处在于,这里每个代理都可以是协调者,因此 Kafka 的领导者选举算法和复制模型缓解了传统模型中提到的问题。
需要注意的一些事项并提供一些背景信息:
这里的“我们不能”真正的意思是“这是一个坏主意,我不想这样做,如果我承认这种可能性,那么我可能无法说服你不要坚持”。
当然,您可以跨微服务实现两阶段提交,但是:
这些问题很难在具有专用网络的位于同一位置的服务器上的几个紧密耦合的服务中进行管理。在具有更多服务器和更高延迟的更加异构的环境中,这是微服务部署的特征,它变得非常非常困难。
微服务的整体思想是松散耦合和独立的服务。由于 2pc 意味着我们有 2 个阶段来提交事务。控制节点将驱动事务,所有其他节点首先响应它们准备好,在第二阶段它们都根据第一阶段提交或回滚。
如果控制节点宕机怎么办?当任何其他节点关闭时会发生什么?由于这个限制,您的整个交易无法通过。在分布式事务中,您的节点可以位于不同的数据中心或区域。响应最慢的节点将使其他节点保持等待状态,同时它们可以继续前进。所以原子性阻碍了性能。
您无法扩展系统,并且服务应该是独立的并且可扩展的整个点都丢失了。
2pc 不是错误的答案,但在大多数情况下,我们会考虑最终的一致性。如果您的系统需要强一致性,那么 2pc 可能是选项。
我建议不是我们不能为微服务实现 XA 或 2PC,而是基于 HTTP 的 API 世界在政治上还没有被接受。在较旧的应用程序中,组件可能代表一组更大的复杂业务逻辑步骤,但也代表跨度、硬件、地理、组织和技术。即我的业务组件可以分布在多个公司中,每个公司都有不同的用户界面。集成所有这些支持的分布式事务 (2PC) 以及传播用户身份等的网络协议。
这有官僚主义和遗留问题。多个可互操作平台支持的标准化分布式事务可以追溯到 80 年代。IT 严重受时尚驱动,如果您过分提倡此类功能,您的工作场所会发生什么。
注意:关于如果控制节点关闭会发生什么的问题。在传统应用程序中,如果提交应用程序的组件在提交过程中死亡,事务最终将超时并在每个组件上回滚。在某些情况下,可以使用可恢复的事务功能。如果提交者在超时之前恢复,它将恢复事务并继续提交。我们在企业应用程序中经常看到这种情况,如果应用程序服务器出现故障,它会恢复正在进行的工作。
当我在咆哮时 :) -一些专家声称 XA 必须在单一平台上实现,比如 JTA。我从来没有发现这是真的,XA 一直为我在数据库、应用程序服务器和大型机之间无缝地工作)
我将详细阐述 Vassilis 的第一点“在大多数情况下,微服务通过 HTTP(一种无状态协议)进行交互,因此全局/XA 事务不适用/不可能。” 作为在微服务领域不使用 2-PC 的最正当理由。
微服务架构带来了应用程序/代码级别的分离,每个微服务在其单独的进程和自己的数据库中运行(每个服务模式的数据库)。每个微服务负责自己的本地事务。只有当所有参与的服务都在单个服务器进程内运行但连接到不同的(分片)数据库或事务性资源(如消息中间件)时,才有可能使用 2-PC。