微服务架构和分布式事务

Posted

技术标签:

【中文标题】微服务架构和分布式事务【英文标题】:Microservices architecture and distributed transaction 【发布时间】:2019-04-14 01:41:35 【问题描述】:

微服务是前一段时间出现的,这种方法有利有弊,但您最终必须面对的问题之一是事务原子性,或者说没有它。企业应用程序通常在 api 级别上具有某种工作单元,但是在您的微服务正在调用另一个微服务(或 api)并且它不了解分布式事务的环境中,当出现问题时,它会引发一些您必须处理的问题:假设你有微服务“为项目付款”。当客户端在内部调用您的微服务 api 时:将一些数据放入拥有的数据库中,创建发票文件,将其发送到另一个微服务,发送电子邮件,也许调用另一个对您的工作单元一无所知的系统。如果这个序列的每个部分都成功了,一切都很好,但问题是如何处理错误,你正在调用的另一个 api 不可用,但是你在许多其他系统中改变了状态,如何从那里恢复?这种情况有什么好的方法吗?

【问题讨论】:

【参考方案1】:

实际上没有正确或错误的问题。但这是我的观点。

让我们分解一下:

微服务是前段时间出现的,这种方法有利有弊,但您最终必须面对的一个问题是事务原子性,或者说没有它

确切地说,通常情况下,您要避免分布式事务,这是重点之一。

企业应用程序通常在 api 级别具有某种工作单元,但在您的微服务正在调用另一个微服务(或 api)的环境中

通常,您不会调用另一个微服务,否则它会变成distributed monolith,其中所有所谓的microservices 相互依赖,就好像它们在单个可执行文件中一样。谈到microservices,就是要让它们尽可能独立。这可以通过各种技术来实现,例如Event Sourcing 就是其中之一。您在哪里定义事件和处理它们的微服务。

当客户在内部调用您的微服务 api 时:将一些数据放入自己的数据库中,创建发票文件,将其发送到另一个微服务,发送电子邮件,也许调用另一个对您的工作单元一无所知的系统。

Event Sourcing 而言,这里指的是Sagas。协调已完成工作的流程。

但是您在许多其他系统中已经改变了状态,如何从那里恢复

如前所述,这是设计问题,形成distributed monolith 的微服务实际上并不是微服务。

一般来说,microservice 不仅仅是一个单独的可执行文件。这是设计实践。如果您以这种方式设计系统,则不会发生此类问题。我建议阅读DDD (Domain Driven Design)Event SourcingCQRSBounded Context 等上的作者。这可能会让你更清楚。就像马丁·福勒、格雷格·杨一样。会尝试在此处添加名称,我会想到它。

【讨论】:

提到的调用流程只是简单的案例,从微服务调用其他api是相当标准的同步做事方式。要求是对我的微服务的调用必须立即返回执行结果,因此在向客户端返回信息之前,我必须确保一切都以成功结束,包括解决与其他 api 的通信错误,这些错误大多无法满足我的需求。跨度> 这就是重点。如果您要求to be sure everything ended 是必需的,那么您的microservice 如何确保一切都结束。微服务负责一些Bounded Context,针对单一类型的任务。否则,如果它知道everything,它似乎不是微服务。它是distributed monolithSaga,选择一个。 microservices 的重点是按照您确定边界和负责的微服务的方式拆分您的架构,然后您需要对它们进行编排,或者相应地设计您的前端 API。 仍然不清楚:所以我的微服务应该只响应客户端“工作已成功启动”?如果客户希望获得整个工作的结果以检查工作是否完成 - 必须订阅总线或使用轮询? 不一定。这取决于你的设计。您将拥有microservice to send email notificationmicroservice to create customermicroservice to put order 等。他们每个人都负责一些明确界定的上下文。那么你如何启动它们,也取决于。例如看看这个:microservices.io/patterns/data/saga.html。如果您可以启动commands 并轮询结果,那是一种方法。如果您需要“阻止”,您可以进行某种包装过程或传奇,这将跟踪执行。这一切都取决于上下文、领域和要求。 好的,所以这是我的要求:微服务应该以同步模式响应客户端。微服务架构如何做到这一点?【参考方案2】:

在Microservice Architecture 中有一个名为“Saga”的模式,它涵盖了您描述的分布式业务事务的问题。

Saga pattern 描述了由不同服务覆盖的一系列本地事务。每个事务都封装在一个服务中。如果本地事务由于违反业务规则而失败,则 saga 会执行一系列补偿事务,以撤消先前本地事务所做的更改。

一般有两种方式来协调sagas:

编舞

在 Saga 模式的编排风格中,每个本地事务都会发布域事件,这些事件会触发其他服务中的本地事务。这可以通过服务调用或发送事件来完成。这通常是解决问题的自然方法。这种方法的缺点在于服务的耦合度增加,因为通常必须从外部域管理事件。

如果业务交易非常短,编排可能是一个很好的解决方案。

编排

使用编排风格实现 Saga 模式是一种不同的方法,其中编排器告诉参与者要执行哪些本地事务。协调器也称为 Saga 协调器。这是放置业务逻辑的地方。 Saga Coordinator 基于声明性业务逻辑调用服务,并在出现异常时处理补偿。

工作流引擎是一种在一个业务事务中编排不同服务的好方法。另请参阅描述如何使用 BPMN 2.0 对 saga 模式进行建模 here

【讨论】:

以上是关于微服务架构和分布式事务的主要内容,如果未能解决你的问题,请参考以下文章

微服务架构中分布式事务实现方案怎样何取舍

微服务架构中分布式事务实现方案怎样何取舍

微服务架构中分布式事务实现方案如何取舍

微服务分布式事务处理支付相关

微服务架构之永恒话题:服务治理与分布式事务

微服务架构下处理分布式事务的典型方案