微服务中数据CQRS操作的事务处理

Posted 程序你好

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务中数据CQRS操作的事务处理相关的知识,希望对你有一定的参考价值。

本文的主要主题是描述如何使用事件源(event sourcing)和CQRS将事件驱动的体系结构与微服务集成。


微服务是独立的,模块化的服务有自己的分层架构。


当微服务共享相同的数据库时,服务之间的数据模型可以遵循与微服务关联的表之间的关系。


例如,有两个微服务在它们自己的容器中运行:“Order”和“Customer”。


订单服务将负责创建、删除、更新和检索订单数据。客户服务将处理客户数据。


一个客户可以有多个订单,这是一对多的关系。由于两个表都位于单个数据库中,因此可以建立一对多的关系。


Order服务和Customer服务虽然运行在不同的容器中,但可以访问来自相同数据库的表。这将利用ACID属性进行适当的事务,当更新客户数据时,还可以更新订单数据以保证适当的原子性。




然而,这种方法有一些局限性。在基于微服务的方法中不建议使用共享数据库,因为如果一个数据模型发生了更改,那么其他服务也会受到影响。

作为微服务最佳实践的一部分,每个微服务都应该有自己的数据库。


订单微服务访问订单数据库,客户微服务访问客户数据库。


在此场景中,无法建立表之间的关系,因为两个表都位于单独的数据库中。


如果客户微服务想要更新订单数据,客户微服务可以将客户id作为请求参数传递给订单微服务的HTTP服务,以更新订单数据库中对应的客户id的订单数据,如下图所示。



微服务中数据CQRS操作的事务处理

这种方法的局限性是无法正确处理事务管理。如果删除了客户数据,也必须删除该客户的相应订单。


虽然这可以通过变通方法来实现,比如在Order服务中调用delete服务,但是原子性不能直接实现。这需要进行定制化处理。


为了克服这个限制,我们可以将事件驱动的体系结构与微服务组件集成。


根据下图,客户数据中的任何更改都将作为事件发布到消息传递系统,以便事件使用者使用数据并更新给定客户更改事件的订单数据。



这种方法的限制是数据库和消息队列发布事件之间的原子更新不容易处理。虽然这些类型的事务可以通过分布式事务管理来处理,但在微服务方法中不建议这样做,因为在所有场景中可能不支持XA事务。


为了避免这些限制,可以在这个微服务体系结构中引入事件源event sourcing


在事件源event sourcing中,任何触发的事件都将存储在事件存储中。对数据没有更新或删除操作,生成的每个事件都将作为记录存储在数据库中。如果事务中出现故障,则将故障事件作为记录添加到数据库中。每个记录条目将一个原子操作。


事件源event sourcing的优点如下:


解决了原子性问题。


维护历史记录和审核记录。


可以与数据分析集成,因为历史记录是维护的。


仍然存在以下几种限制:


对事件存储中的最新数据或特定数据块的查询涉及复杂的处理。


为了使数据最终保持一致,这涉及到异步操作,因为数据流与消息传递系统集成。


涉及插入和查询数据的模型是相同的,可能会导致与事件存储进行映射的模型的复杂性。


在存储所有记录的历史时,事件存储容量必须更大。


现在我们将CQRS(命令查询责任隔离)与事件源集成起来,以克服上述限制。



CQRS是微服务体系结构中使用的另一种设计模式,它将为数据库中的插入操作提供单独的服务、模型和数据库。它充当命令层,并为充当查询层的查询数据提供单独的服务、模型和数据库。


read数据库可以存储一个非规范化模型,其中可以利用NoSQL(水平可伸缩的)等数据库。


命令层用于将数据插入数据存储中。查询层用于从数据存储中查询数据。



消息队列中发布的事件将由事件使用者使用并更新读存储中的数据。


在用作查询模型时,客户微服务需要检索调用查询服务的客户数据,查询服务从读取存储中获取数据。


类似地,跨微服务发布的事件也必须通过消息队列传递。


与事件来源和微服务集成的CQRS的优点是:


利用微服务实现与独立数据库的模块化。


利用事件源来处理原子操作。


维护历史/审计数据,以进行事件源分析。


具有用于读取和插入操作的独立模型和服务的CQRS。


请求负载可以分布在读取和插入操作之间。


当读取和插入服务之间分配负载时,读取操作可以更快。


读模型或DTO不需要将所有字段作为命令模型,而读模型可以具有客户机视图所需的字段,从而节省读存储的容量。


这种方法的局限性是:


基础设施的额外维护,比如为命令和查询请求建立单独的数据库。


模型应该以最优的方式设计,否则将导致处理和故障排除的复杂性。



以上是关于微服务中数据CQRS操作的事务处理的主要内容,如果未能解决你的问题,请参考以下文章

01 | MySQL事务处理

3.16 Go微服务实战(微服务理论) --- Go语言基于ES-CQRS的微服务实践

3.16 Go微服务实战(微服务理论) --- Go语言基于ES-CQRS的微服务实践

使用gRPC, NATS, CockroachDB构建EventSourcing/CQRS的微服务

.NET CQRS-一种读写分离的数据处理模式

分布式事务-金融业微服务实践案例