微服务的分布式事务模式比较 | RedHat


作为 Red Hat 的一名咨询架构师,我有幸参与了大量客户项目。每个客户都会带来自己的挑战,但我发现了一些共同点。大多数客户想知道的一件事是如何协调对多个记录系统的写入。回答这个问题通常涉及对双重写入、分布式事务、现代替代方案以及每种方法可能的故障场景和缺点的详细解释。通常,此时客户会意识到将单体应用程序拆分为微服务是一个漫长而复杂的过程,通常需要权衡取舍。(banq注:如果稍微懂一些业务DDD分析,这种纯技术的分布式事务其实是一个伪概念,但是为了展示纯技术人员如何在分布式事务上弄巧成拙,特大意翻译这篇文章要义,详细点击标题)
本文没有深入讨论事务,而是总结了协调写入多个资源的主要方法和模式。我知道您过去可能对这些方法中的一种或多种有好的或坏的经验。但实际上,在正确的上下文和正确的约束下,所有这些方法都可以正常工作。技术主管负责为他们的上下文选择最佳方法。
正如您可能已经从本文中猜到的那样,在微服务架构中处理分布式事务没有正确或错误的模式。每种模式都有其优点和缺点。每个模式都解决了一些问题,同时又依次产生了其他问题。图 12 中的图表简要总结了我讨论过的双写入模式的主要特征。

无论您选择哪种方法,您都需要解释和记录决策背后的动机以及您选择的持久架构后果。您还需要获得将长期实施和维护系统的团队的支持。我喜欢根据数据一致性和可扩展性属性来组织和评估本文中描述的方法,如图 13 所示。

作为一个很好的起点,我们可以评估各种方法,从最具可扩展性和高度可用的方法到最不具有可扩展性和可用性的方法。

  • 高:并行管道和编排

如果您的步骤暂时分离,那么在并行管道方法中运行它们可能是有意义的。您可能可以将这种模式应用于系统的某些部分,但不能应用于所有部分。接下来,假设处理步骤之间存在时间耦合,并且某些操作和服务必须先于其他操作和服务发生,您可能会考虑编排方法。使用服务编排,可以创建一个可扩展的、事件驱动的架构,其中消息通过分散的编排过程从一个服务流向另一个服务。在这种情况下,使用 Debezium 和 Apache Kafka 实现的发件箱模式(例如Red Hat OpenShift Streams for Apache Kafka)特别有趣并受到关注。
  • 中:编排和两阶段提交

如果编舞不合适,并且您需要一个负责协调和决策的中心点,那么您可以考虑编排。这是一种流行的架构,提供基于标准和自定义的开源实现。虽然基于标准的实现可能会强制您使用某些事务语义,但自定义编排实现允许您在所需的数据一致性和可伸缩性之间进行权衡。
  • 低:模块化单体

如果您在频谱中更进一步,很可能您对数据一致性有非常强烈的需求,并且您已经准备好以重大的权衡来支付它。在这种情况下,通过两阶段提交的分布式事务将适用于某些数据源,但它们很难在为可扩展性和高可用性而设计的动态云环境中可靠地实现。在这种情况下,您可以一直采用旧的模块化单体式方法,并伴随着从微服务运动中学到的实践。这种方法确保了最高的数据一致性,但以运行时和数据源耦合为代价。
 
结论
在具有数十个服务的大型分布式系统中,不会有一种方法适用于所有服务,而是将其中一些方法组合起来并应用于不同的上下文。您可能在共享运行时部署了一些服务,以满足有关数据一致性的特殊要求。您可以选择两阶段提交以与支持 JTA 的遗留系统集成。您可能会编排复杂的业务流程,并对其余服务使用编排和并行处理。最后,你选择什么策略并不重要;重要的是出于正确的原因故意选择策略并执行它。