聊聊分布式解决方案Saga模式

这篇具有很好参考价值的文章主要介绍了聊聊分布式解决方案Saga模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Saga模式

Saga模式使用一系列本地事务来提供事务管理,而一个本地事务对应一个Saga参与者,在Saga流程里面每一个本地事务只操作本地数据库,然后通过消息或事件来触发下一个本地事务,如果其中一个本地事务失败了,Saga就会执行一系列补偿事务来实现回滚操作。(补偿事务简单来讲就是对之前本地事务做的修改导致不一致的情况执行反向操作来消除掉不一致的状态)。

聊聊分布式解决方案Saga模式

上图左侧是正常的事务流程,当执行事务T3时出现异常,则开始反向执行右边的事务补偿,其中C3是T3的补偿,C2是T2的补偿,C1是T1的补偿,将T3,T2,T1已经修改的数据做补偿处理。

实现分析

对Saga事务流程进行排序,当Ti事务完成之后,需要决定下一步要怎么进行。如果成功执行T(i+1)分支,如果失败,则执行C(i-1)分支。这类似一个工作流或是状态机的概念。从实现来看,有两种方式:

集中式实现

集中式协调器负责服务调用以及事务协调(Orchestration)即编排实现:集中式协调器负责服务调用以及事务协调。Saga提供一个控制类,其方便参与者之间的协调工作。事务执行的命令从控制类发起,按照逻辑顺序请求Saga的参与者,从参与者那里接受到反馈以后,控制类在发起向其他参与者的调用。所有Saga的参与者都围绕这个控制类进行沟通和协调工作。

聊聊分布式解决方案Saga模式

去中心化实现

分布式的实现方式——通过事件驱动的方式进行事务协调(Choreography)即协同实现:Saga参与者(子事务)之间的调用、分配、决策和排序,通过交换事件进行进行。是一种去中心化的模式,参与者之间通过消息机制进行沟通,通过监听器的方式监听其他参与者发出的消息,从而执行后续的逻辑处理。由于没有中间协调点,靠参与者自己进行相互协调。

聊聊分布式解决方案Saga模式

实现比对

我个人认为在计算机的世界里没有银弹!任何的解决方案只能说是合适与不合适,而没有完美的契合并解决。

如上两种解决方式都有一定的弊端;对于集中式的实现方式,其弊端如下:

  • 必须额外实现一个协调器,相当于增加了系统复杂度
  • 需要考虑协调器自身发生故障时应对措施

分布式的实现方式,其弊端如下:

  • 添加新的事务步骤时比较麻烦,需要确定哪个Saga参与者订阅了哪个事件。
  • 有可能出现循环依赖的问题,每一个Saga参与者都可能订阅其他参与者的事件。
  • 集成测试异常复杂,需要运行所有服务来模拟事务。

实现方式

目前看到市面上已经有很多的saga实现,他们都具备saga的基本功能。

这些实现,可以大致可以分为两类

状态机实现
Seata

这一类的典型实现有seata的saga,他引入了一个DSL语言定义的状态机,允许用户做以下操作:

在某一个子事务结束后,根据这个子事务的结果,决定下一步做什么
能够把子事务执行的结果保存到状态机,并在后续的子事务中作为输入
允许没有依赖的子事务之间并发执行。

  • 优点:
    功能强大,事务可以灵活自定义

  • 缺点:
    状态机的使用门槛非常高,需要了解相关DSL,可读性差,出问题难调试。官方例子是一个包含两个子事务的全局事务,Json格式的状态机定义大约有95行,较难入门。
    接口入侵强,只能使用特定的输入输出接口参数类型,在云原生时代,对强类型的gRPC不友好(gRPC协议,在TM拿不到用户自定义的输入输出pb文件,因此无法解析结果中的字段)

Masstransit Saga State Machines

Masstransit是一个免费、开源的.NET 分布式应用框架。其功能之一就是提供了强大的状态机编排能力。通过集成消息队列中间件,基于C#高效易用的语法,支持了状态机的编排。其使用语法示例如下

///// 下单 初始化 → 已初始化
///// 翻译:当前状态是Initial且执行OrderProcessInitializationEvent事件时,Then(然后)执行xxxx,最后将状态转换(TransitionTo)为OrderProcessInitializedState

During(Initial,
    When(OrderProcessInitializationEvent)
        .Then(x => {
            x.Saga.OrderStartDate = DateTime.Now;
        })
        .TransitionTo(OrderProcessInitializedState));

///// 库存 已初始化 → 校验库存
///// 翻译:当前状态是OrderProcessInitializedState且执行CheckProductStockEvent事件时,Then(然后)执行xxxx,最后将状态转换(TransitionTo)为CheckProductStockState

During(OrderProcessInitializedState,
    When(CheckProductStockEvent)
    .Then(x => {
        System.Console.WriteLine(x.Message.OrderId);
        })
        .TransitionTo(CheckProductStockState));

///// 支付 校验库存 → 支付
During(CheckProductStockState,
    When(TakePaymentEvent)
        .TransitionTo(TakePaymentState));

///// 订单 支付 → 创建订单
During(TakePaymentState,
    When(CreateOrderEvent).Then(x => {
        System.Console.WriteLine(x.Message.OrderId);
    })
        .TransitionTo(CreateOrderState));

///// 创建订单失败
DuringAny(When(CreateOrderFaultEvent)
    .TransitionTo(CreateOrderFaultedState)
    .Then(context => context.Publish<Fault<TakePaymentEvent>>(new {context.Message})));

///// 支付失败
DuringAny(When(TakePaymentEventFaultEvent)
    .TransitionTo(TakePaymentFaultedState)
    .Then(context => context.Publish<Fault<CheckProductStockEvent>>(new {context.Message})));

///// 校验库存失败
DuringAny(When(CheckProductStockFaultEvent)
    .TransitionTo(CheckProductStockFaultedState)
    .Then(context => context.Publish<Fault<OrderProcessInitializationEvent>>(new {context.Message})));

///// 下单失败
DuringAny(When(OrderProcessInitializationFaultEvent)
    .TransitionTo(OrderProcessInitializedFaultedState)
    .Then(context => context.Publish<OrderProcessFailedEvent>(new {OrderId = context.Saga.CorrelationId})));

///// 下单流程失败
DuringAny(When(OrderProcessFailedEvent)
    .TransitionTo(OrderProcessFailedState));

流程逻辑:当客户端请求下单服务时,业务逻辑正常执行,执行成功后发布事件到消息队列,状态机监听到对应的订单事件后,修改当前状态,发布事件标识成功或失败,订单服务业务监听事件,响应状态的调整(一般是标识或回滚业务)。

聊聊分布式解决方案Saga模式

  • 优点
    方便简单,而且强大,流程编排能力很强。

  • 缺点:引入了rabbitmq,有中间件依赖。

可参考实现:
使用 Masstransit中的 Request/Response 与 Courier 功能实现最终一致性
分布式事务 | 基于MassTransit的StateMachine实现Saga编排式分布式事务

非状态机实现

这一类的实现有eventuate的saga,dtm的saga。

在这一类的实现中,没有引入新的DSL来实现状态机,而是采用函数接口的方式,定义全局事务下的各个分支事务。

优点:

简单易上手,易维护

缺点:
难以做到状态机的事务灵活自定义

ACID与Saga

聊聊分布式解决方案Saga模式文章来源地址https://www.toymoban.com/news/detail-463156.html

到了这里,关于聊聊分布式解决方案Saga模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 分布式锁解决方案

    由于分布式或者集群部署项目时,在某些业务场景下需保证资源的原子性、一致性和互斥性。 如果把房子比作资源,通俗的来讲,我无论在那个城市生活,这个房子我先租的,再没有退房的前提下,别人都不能用 目前最流行的解决方案 redisson 分布式锁 zookeeper 分布式锁 mav

    2024年02月12日
    浏览(39)
  • 分布式websocket解决方案

    websocket基础请自行学习,本文章是解决在分布式环境下websocket通讯问题。 在单体环境下,所有web客户端都是连接到某一个微服务上,这样消息都是到达统一服务端,并且也是由一个服务端进行响应,所以不会出现问题。 但是在分布式环境下,我们很容易发现,客户端连接的

    2024年02月13日
    浏览(36)
  • ChatGPT:分布式事务解决方案

    随着互联网的发展和技术的不断更新,越来越多的应用程序开始采用分布式架构。然而,由于数据和处理逻辑的分散性和异构性,分布式环境下的事务处理面临着许多挑战。这时候就需要采用分布式事务来确保系统的一致性和可靠性。 分布式事务是指在分布式系统中,涉及多

    2023年04月12日
    浏览(82)
  • 分布式ID解决方案对比

    在复杂的分布式系统中,往往需要对大量的数据进行唯一标识,比如在对一个订单表进行了分库分表操作,这时候数据库的自增ID显然不能作为某个订单的唯一标识。除此之外还有其他分布式场景对分布式ID的一些要求: 趋势递增:  由于多数RDBMS使用B-tree的数据结构来存储索

    2024年02月04日
    浏览(32)
  • 【SpirngCloud】分布式事务解决方案

    1.1 CAP 理论 1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标: Consistency(一致性):用户访问分布式系统中的任意节点,得到的数据必须一致 Availability(可用性):用户访问集群中的任意健康节点,必须能得到响应,而不是超时或拒绝 Partition tolerance(分区容

    2024年02月15日
    浏览(39)
  • Redis 分布式锁解决方案

    我们日常在电商网站购物时经常会遇到一些高并发的场景,例如电商 App 上经常出现的秒杀活动、限量优惠券抢购,还有我们去哪儿网的火车票抢票系统等,这些场景有一个共同特点就是访问量激增,虽然在系统设计时会通过限流、异步、排队等方式优化,但整体的并发还是

    2023年04月22日
    浏览(40)
  • 无限容量分布式文件存储解决方案

    常见分布式文件系统比较 常见的分布式文件系统有GFS、HDFS 、Ceph 、GridFS 、TFS、FastDFS等。各自适用于不同的领域。 类 Google FS 都支持文件冗余备份,例如 Google FS、TFS 的备份数是 3。一个文件存储到哪几个存储结点,通常采用动态分配的方式。采用这种方式,一个文件存储到

    2024年02月11日
    浏览(37)
  • 浅谈分布式事务及解决方案

    在讲述分布式事务的概念之前,我们先来回顾下事务相关的一些概念。 就是一个程序执行单元,里面的操作要么全部执行成功,要么全部执行失败,不允许只成功一半另外一半执行失败的事情发生。例如一段事务代码做了两次数据库更新操作,那么这两次数据库操作要么全部

    2024年02月08日
    浏览(44)
  • 分布式锁-Redis红锁解决方案

    分布式锁(多服务共享锁) 在分布式的部署环境下,通过锁机制来让多客户端互斥的对共享资源进行访问控制分布式系统不同进程共同访问共享资源的一种锁的实现。如果不同的系统或同一个系统的不同主机之间共享了某个临界资源,往往需要互斥来防止彼此干扰,以保证一

    2024年02月06日
    浏览(33)
  • 【业务功能篇73】分布式ID解决方案

    1. 基于UUID 2. 基于DB数据库多种模式 ( 自增主键、 segment) 3. 基于Redis 4. 基于ZK、ETCD 5. 基于SnowFlake 6. 美团Leaf (DB-Segment 、 zk+SnowFlake) 7. 百度uid-generator () UUID: UUID 长度 128bit , 32 个 16 进制字符,占用存储空间多,且生成的 ID 是无序的 ; 对于 InnoDB 这种聚集主键类型的引擎来说,

    2024年02月12日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包