dubbo、zookeeper、spring cloud、redis都能否做分布式事务控制?

如果能的话 能大致举例怎么做么?哪种用得比较多?谢谢
关注者
324
被浏览
48,160

15 个回答

一般分布式事务处理模式包括:2阶段提交、3阶段提交、TCC(Try-Confirm-Cancel)、可靠消息(消息队列、数据库表)、SAGAS长事务、补偿性事务。具体采用哪一种分布式事务处理模式,需要根据自己业务场景来选择合适的机制。

duboo、spring cloud都可以算作是SOA框架,分布式事务控制支持依赖其他组件,例如通过JTA(2阶段、3阶段)、ActiveMQ消息中间件、ByteTCC(TCC)等。

zookeeper、redis可以支持分布式锁,分布式锁是分布式事务的核心,但分布式锁不等同于分布式事务。

redis对分布式锁的支持主要通过setnx,在使用redis分布式锁时候,一定要注意处理加锁客户端异常导致锁资源没有正常释放的情况(例如调用端down掉),在调用setnx时候需要加上对锁超时时间的判断。

zookeeper对分布式锁的支持可以直接使用zookeeper curator-recipes客户端。

分布式事务是个很大的话题,三言两语恐怕说不清。你说的这些中间件还有框架都没提供现成的分布式事务解决方案,dubbo本身虽然是个分布式服务框架,但他没提供解决分布式事务的功能,其他比如zk和redis有提供分布式锁,但这跟提供分布式事务解决方案是两码事。

分布式事务是在应用服务化后首先碰到的一个问题(其他比如服务治理这个先不谈),实际上可能都不用服务化,你随便来个分库就会遇到事务的不一致问题。目前解决的办法有基于XA的2pc两阶段提交,实际上就是整个事务过程由事务管理器和资源管理器来共同参与。这么一说可能题主就明白了这是位于资源层面的解决方案,说白了就是你的数据库或者MQ要支持两阶段提交协议,由于在整个事务过程中会一直锁定资源,而且涉及到网络操作,那这个东西就不太可靠,而且会影响性能,扩展性和可用性都不友好,同时对于服务层面的分布式它是搞定不定的。所以后面又搞出来个tcc,这个类似2pc,只是它是位于业务层面,基本的思路是把比较长的分布式事务拆分成本地的短事务。这需要结合业务的特点去设计,比如买10块钱的东西,针对支付这个服务,在进行扣费的时候先有个冻结用户10块钱的动作,这个就是try。等到后面tcc框架发起confirm操作时才真正把10块钱扣掉,如果tcc框架发起cancel操作则把10块钱解冻。需要注意的是由于confirm和cancel可能失败,因此可以结合全局事务ID设计成幂等性的接口。

上面两种从某种程度上来讲都能提供比较强的一致性,但是有很多场景是不需要这种强一致性的。根据CAP(一致性、可用性、可靠性)的理论,鱼和熊掌不可兼得,可靠性是必须要的,所以需要在C和A之间做平衡,实际上在互联网领域A也是必须的,因此就不得不在C上做文章。于是有了弱一致或者最终一致,它不要求你在做完一个操作后能立马看到效果,只要在可接受的时间内看到正确的结果即可。这方面的内容epay的架构师有过介绍,目前业界用这种的比较多,Sina Visitor System 这篇文章讲解的比较详细。其解决分布式事务的思路就是避免分布式事务,具体来说就是利用本地事务+异步消息+重试+幂等去保证整个系统数据的最终一致性。

如果您正在找分布式事务的解决方案,那么上述几个都不是匹配的解决方案,推荐您一个小而美的分布式事务开源项目yedf/dtm,接入非常简单,同时还大大简化了业务处理,它与seata的对比:

特性DTMSEATA备注
支持语言Golang、python、node 及其他Javadtm 可轻松接入一门新语言
异常处理子事务屏障技术手动处理dtm 解决了幂等、悬挂、空补偿
TCC 事务
XA 事务
AT 事务AT 事务与 XA 事务类似
SAGA 事务简单模式状态机复杂模式dtm 的状态机模式在规划中
事务消息dtm 提供类似 rocketmq 的事务消息
通信协议HTTPdubbo 等协议,无 HTTPdtm 后续将支持 grpc 类协议

分布式事务控制,微软很多年前的MTS,被证明相当优秀

dubbo 和 spring-cloud 是目前比较好的微服务框架,zookeeper 可以用来做注册中心,redis 更多的使用来用作分布式缓存,同时通过 zookeeper 和 redis 都可以实现分布式锁,因此都是分布式系统中常用的中间件。

分布式事务是为了分布式系统中保证不同数据库的数据一致性,它是分布式系统中至关重要但是又很难的一点,很多大厂和大神已经做过了很多的实践。首先我们来回顾一下数据库事务的 ACID 特性:

  1. 原子性(A):在整个事务中的所有操作,要么全部完成,要么全部不做,没有中间状态。
  2. 一致性(C):事务的执行必须保证系统的一致性。
  3. 隔离性(I):事务与事务之间不会互相影响,一个事务的中间状态不会被其他事务感知。
  4. 持久性(D):单事务完成了,那么事务对数据所做的变更就完全保存在了数据库中,即使发生停电,系统宕机也是如此。

所谓事务都是要满足 ACID 的要求,对于 Java 应用而言,本地事务更多的是通过 Spring 来进行本地事务管理。分布式事务实现方式一般有以下几种常用的解决方案:

1、两阶段提交(2PC):

  • 优点: 尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。
  • 缺点: 实现复杂,牺牲了可用性,对性能影响较大,不适合高并发高性能场景。

2、补偿事务(TCC):核心思想是针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作,它大致分为三个阶段:(1)Try 阶段主要是对业务系统做检测及资源预留(2)Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。(3)Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。

  • 优点: 跟 2PC 比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
  • 缺点: 缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

3、本地消息表(异步确保):核心思想是将分布式事务拆分成本地事务进行处理,基本思路是消息生产方和消息消费方都执行本地事务,如果消息消费方执行失败则发送失败消息给生产方,进行相应的业务补偿,实现最终一致性。

  • 优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。
  • 缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会增加很多工作量。

4、MQ 事务消息:通过第三方 MQ 的事务消息实现,比如阿里的 RocketMQ 或 升级的 消息队列服务,要实现事务消息大概有三个步骤:(1) 发送Prepared消息 (2) update DB (3) 根据update DB结果成功或失败,Confirm或者取消Prepared消息。

  • 优点: 实现了最终一致性,不需要依赖本地数据库事务。
  • 缺点: 实现难度大,主流MQ不支持。

我们在使用过程中需要根据实际情况来选择合适的方案,目前我司 VPGAME 大量分布式场景下更多采用的是 TCC 事务补偿的形式,面对复杂的分布式环境采用业务重试和回调来实现数据的最终一致性,欢迎各路大神一起来探讨。

分布式系统架构中,分布式事务问题是一个绕不过去的挑战。而微服务架构的流行,让分布式事问题日益突出!下面我们以电商购物支付流程中,在各大参与者系统中可能会遇到分布式事务问题的场景及对应的解决方案进行分析!

假设三大参与平台(电商平台、支付平台、银行)的系统都做了分布式系统架构拆分,按上数中的流程步骤进行分析:

1、电商平台中创建订单:预留库存、预扣减积分、锁定优惠券,此时电商平台内各服务间会有分布式事务问题,因为此时已经要跨多个内部服务修改数据;

2、支付平台中创建支付订单(选银行卡支付):查询账户、查询限制规则,符合条件的就创建支付订单并跳转银行,此时不会有分布式事务问题,因为还不会跨服务改数据;

3、银行平台中创建交易订单:查找账户、创建交易记录、判断账户余额并扣款、增加积分、通知支付平台,此时也会有分布式事务问题(如果是服务化架构的话);

4、支付平台收到银行扣款结果:更改订单状态、给账户加款、给积分帐户增加积分、生成会计分录、通知电商平台等,此时也会有分布式事务问题;

5、电商平台收到支付平台的支付结果:更改订单状态、扣减库存、扣减积分、使用优惠券、增加消费积分等,系统内部各服务间调用也会遇到分布式事问题;

余下全文请查看: 微服务架构的分布式事务解决方案