微服务架构之分布式事务解决方案


一、微服务

微服务概述

在这里插入图片描述
dubbo和springcloud是流行的微服务框架,
电商网站架构
在这里插入图片描述

二、分布式事务

在这里插入图片描述
假如下单操作,需要调用库存微服务和交易微服务,在传统的一个war包的项目中,用Spring提供的事务注解可以实现,但是微服务架构中不可以使用,因为Spring只能保证一个jvm下事务有效,这时候就需要微服务事务。

在这里插入图片描述
库存服务没动,交易服务动了容易超卖。

补偿:
协调器(zk)最后发两个commit操作,第一次成功,第二次失败可以写一个日志,可以人工或者定时任务检查日志,全局事务生成一个唯一的txid写入两个日志,看两个txid相同的是否都成功,然后自动回滚,自动不行就人工介入,没法100%解决问题,没有绝对完美的方案。

三、XA/JTA规范

在这里插入图片描述
在这里插入图片描述
weblogic也可以实现JTA。
在这里插入图片描述
在这里插入图片描述
XA
在这里插入图片描述
在这里插入图片描述

rm1.end(xid1,XAResource.TMSUCCESS);标记已经完成,不能做其他事情。

两个预提交都ok就同步提交两个事务,如果不是就同时回滚。除非 rm1.commit(xid1,onePhase);这里网断了,程序挂掉了。但是基本不可能,就算出现了也可以写入日志解决,就是这个事务太重了。

基于JTA的atomikos实现只能单JVM,多数据源。
XA是两阶段规范,JTA是java根据XA实现的一套接口规范

四、柔性事务

JTA实现效率太低,追求高效率不能使用这种方案。

CAP理论

在这里插入图片描述
P是必须解决的,CA是需要平衡的

BASE理论

在这里插入图片描述
下单和送优惠券应该一起执行,可以下单之后,mq延迟送优惠券,弱一致性,等监听到就送优惠券,最终一致。

最大努力通知方案

在这里插入图片描述

TCC两阶段补偿型方案

在这里插入图片描述
在这里插入图片描述
提供预留机票接口,调成功再进入第二阶段。确认和取消也是航空公司提供的API,基于TCC需要被调用方来提供接口。
锁定状态就是soft state
在这里插入图片描述

TCC与XA/JTA对比

在这里插入图片描述
在这里插入图片描述
资源指数据库、消息队列,第三方的中间件。
TCC每一步小操作事务都会提交、分步提交,JTA是一个大框子里面都锁着的没有任何提交
TCC方案没有提升下单操作的的性能而是提升了系统整体的性能。
XA在资源层面全锁住了,TCC在业务层面没做完一步就释放掉资源,达成了最终一致性,不是强一致性。
如果阶段二一步操作成功,另一步操作失败,概率很小,如果一定要考虑就可以重试6次,实现幂等性。操作失败有多种可能,有可能内部API成功,但是网络超时,美团收到的结果是超时,重试就又调了确认的接口。不可能要再生成一张机票,可以查一下机票有没有生成,如果预留状态改成了出票,就直接返回成功。实现幂等操作有很多方案,要考虑并发。还有可能第一次调用成功了,第二次查询是预留状态,就是双十一并发系统那种解决方案。要是API就是挂掉了,就日志去补偿回滚,或者人工介入等。

基于Rocket MQ的方案

在这里插入图片描述
阿里巴巴会用这种方式,支付宝用TCC方式。
第一步操作下单,第二步异步操作发mq送优惠券,最终一致,如果第一步下单成功,第二步发mq,mq接收消息成功了,因为网络问题,订单服务收到的是超时,把下单操作回滚了,但是消息发出去要发优惠券的,没有实现一致性。
基于MQ解决,先发一条消息,先生成一个订单号ID,把订单号写到消息里面发到mq里面,叫做预发送消息,有一个预接收状态,这是一个中间状态。消息处于中间状态,优惠券收不到这个消息,就不会发送优惠券,现在做下单业务逻辑,当数据库生成了order订单,再给mq发送一个确认消息,把这个中间状态改变成发送状态,发送给优惠券方,优惠券再发出去,要注意幂等操作。处理发券业务逻辑成功之后再返回一个ack,mq就把这条消息删掉了。这里还有两个小问题,生成订单给mq发送确认消息时容易失败,不能改变消息的中间状态,优惠券没有成功,最终一致性又没有保证。解决方案:补偿。消息队列可以定时查询一下,消息队列里面有订单号,查一下订单有没有生成,如果生成了,就把中间状态修改了,发送优惠券,就保证了最终一致性。

三种方案通性:最终一致性、补偿、软状态(中间状态)

其他mq没有中间状态,怎么解决?
自己加一个服务去实现中间状态就可以了。
在这里插入图片描述

要是通过这两阶段怎么封装一个框架去实现TCC?

预留第一阶段操作只有几种情况,分布式框架就是用来解决第二阶段的自动化,需要控制两阶段的业务场景很多,比如支付,下单减库存,订单状态改成支付,跨支付中心状态,金额也要扣了,这些如果交给普通程序员去实现,程序员就不太靠谱,不是所有的情况都想到位,会忘记某种情况,会产生严重的bug,分布式框架就是不让程序员去做第二阶段操作,由框架去做两个同时确认或者同时取消的操作。

tcc-transaction是开源的tcc框架。
在这里插入图片描述
try方法,confirm方法,cancel方法,实现了一个@Compensable注解,只要调预留接口,通过这个注解配置到这个方法上,TCC根据结果自动去调用confirm、cancel方法,TCC就相当一个协调器。

总结

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值