微服务Saga分布式事务是一种反模式


Saga通常被定位为处理分布式事务的更好方法。我认为讨论佐贺的优点和缺点没有意义,因为Saga根本不应该在基于微服务的系统中使用:
如果你需要跨几个微服务的分布式事务,很可能你错误地定义和分离了领域。

作为分布式系统的微服务
任何基于微服务的系统都是一个分布式系统。准确地说,它是一个尽可能简单的基本版本。

这种分布式系统不维持任何形式的共识。换句话说,这种系统

  • 缺乏任何协调节点的内置手段
  • 缺乏获取节点信息的内置方式
  • 如果节点需要通信,这种通信必须是业务逻辑的一部分

这些特性导致基于微服务的系统无法执行某些任务,例如,执行事务;或保持一致性(即使是最终的一致性);或者在所有必要节点都正常运行的情况下获取信息(即系统是否可用)。

因此,如果一个节点需要从另一个节点获取信息,它就应该明确地向远程服务发出请求,作为业务步骤之一。这看起来与浏览器和网络服务器等之间的交互惊人地相似。

请注意,这种交互意味着每个请求彼此完全独立。如果有必要,所有事务都不会跨越请求边界。

只有在域(和数据)如此深度分离的情况下,要求微服务独立、单独地维护自己的数据才有意义。或者要求独立的可部署性或可测试性。或者将向另一个节点的请求(可能会失败)作为业务逻辑中的一个明确步骤(并在此级别上处理失败)。

领域大小问题
一旦我们开始根据数据治理进行域分离,我们可能很快就会意识到,在绝大多数情况下,微服务看起来很像传统单体,它们应该处理的域很大。或者意识到传统单体其实就是微服务。出现这种情况的原因是,大多数组织只有数量非常有限的真正独立的域。最常见的情况是“一个”。

不幸的是,整个微服务的炒作都忽略了这一事实,我们得到的 "最佳实践"、"设计模式"、书籍、文章等,都在将松散耦合、可独立部署的服务这一最初理念延伸到不适合的领域。这导致了令人震惊的毁灭性后果:

  • 我们在可靠的系统(云基础设施)之上构建了不可靠的系统(见上文关于微服务是什么样的分布式系统的介绍)。
  • 我们会得到丑陋的、本质上已损坏的设计,其中各层混杂在一起,通信错误处理/重试等和事务处理发生在业务逻辑层
  • 我们将数据分割成若干部分,然后试图收集这些部分来处理请求,从而带来不可预测且几乎无法控制的尾部延迟
  • 我们得到的系统无法确保数据完整性和一致性
  • 我们应该在部署前进行端到端测试,因为无法保证新版本的服务不会破坏整个系统。这就完全排除了服务的独立可测试性和可部署性

上述清单肯定是不完整的。不正确地应用微服务会造成各种危害。尤其是与 Spring 等 "云原生""微服务 "框架相结合时,整个系统会变成一堆缓慢移动的单体。

作为微服务固有属性和天然契合点的所有优势和要求要么消失,要么变成相当痛苦和昂贵的障碍。

不幸的是,所有这些考虑因素可能会导致领域比传统微服务设计所能接受的大得多。没关系,这只是意味着我们不应该使用微服务,那么我们可以使用什么呢?让我们来看看。

处理大域
由于我们要处理的是一个大而单一的域,因此我们需要使用一些能够维持共识的东西。至少有三种选择:

  • 模块化单体(也称 modulith)
  • 事件驱动架构
  • 基于集群的架构

模块化单体
该方案解决了大多数单片机的痛点,尤其是可维护性和并发开发。这主要是通过应用 DDD 和其他技术改进设计来实现的。
这种方法能够访问所有数据、执行常规事务,而且不存在通信错误,因此对许多用例来说都很有吸引力。
此外,这种方法更容易在系统演进过程中以原子方式进行修复/返工/重构/更新。

需要注意的是,内部子服务不需要维护自己的数据(但必要时也可以)。在这种方法中,共享数据通常是固有的、自然的,因为我们谈论的是单一领域。因为这毕竟只是一个单体,所以不存在维护共识或部署/监控/维护的问题。

模块单体的主要缺点是可扩展性有限。在某些时候,可能需要切换到另一种设计。
幸运的是,模块化大大简化了转换过程。

事件驱动架构(EDA)
EDA 是一种相当流行的选择,虽然它经常在微服务的背景下被提及,但这是不正确的。在设计上,EDA 利用消息代理或发布-子服务形式的可靠数据共享基础设施,这与微服务维护数据的方式明显冲突。总之,这种架构在很多资料中都有详细描述,因此我认为没有必要在此重复。
它的主要缺点是在依赖基础设施、复杂部署、监控等方面与微服务相似。

基于集群的架构
这种设计相当罕见。它有几个优点,但有几个值得单独指出:

  • 从 modulith 过渡到这种架构非常简单
  • 不依赖基础设施。通常情况下,整个系统都是独立的,可以部署在办公场所、云或多个云中
  • 部署简单--只有一个可部署的工件
  • 近乎线性的可扩展性
  • 真正的容错--节点故障不会导致整个系统瘫痪,也不会导致请求返回错误。只是处理请求的速度会慢一些
  • 资源利用率高,细粒度两级扩展

结论
微服务被认为是一种解决问题的方法,但盲目应用却弊大于利。主要问题在于没有明确的标准来确定微服务的适用范围。我不抱任何幻想,我的这篇文章不会解决这个问题,但至少它提供了一些有意义的标准来评估哪些地方不应该使用微服务。

相关主题
分布式事务可能是个伪概念