分布式事务之最终一致的Mq实现

问题的起源

分布式系统的特性

对分布式系统有过研究的读者,可能听说过“CAP定律”、“Base理论”等,非常巧的是,化学理论中ACID是酸、Base恰好是碱。这里我们不对这些概念做过多的解释,有兴趣的读者可以查看相关参考资料。

这里针对一致性我们做个简单的科普:

分布式事务有强一致,弱一致,和最终一致性这三种:

强一致

当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。

弱一致

系统并不保证续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

最终一致

弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统

在分布式系统中,同时满足“CAP定律”中的“一致性”、“可用性”和“分区容错性”三者是几乎不可能的。在互联网领域的绝大多数的场景,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证“最终一致性”,只要这个最终时间是在用户可以接受的范围内即可,这时候我们只需要用短暂的数据不一致就可以达到我们想要效果。

实例描述

比如有订单,库存两个数据,一个下单过程简化为,加一个订单,减一个库存。 而订单和库存是独立的服务,那怎么保证数据一致性。

这时候我们需要思考一下,怎么保证两个远程调用“同时成功”,数据一致?

请大家先注意一点远程调用最郁闷的地方就是,结果有3种,成功、失败和超时。 超时的话,成功失败都有可能。

一般的解决方案,大多数的做法是借助mq来做最终一致。

如何实现最终一致

实例分析

我们是怎么利用Mq来达到最终一致的呢?下面让我们来一起进行详细的分析:

订单业务分析

首先,拿我们上面提到的订单业务举例:

  • 在我们进行加订单的过程中同时插入logA(这个过程是可以做本地事务的)
  • 然后可以异步读取logA,发mqA
  • B端接收mqA,同时减少库存,B这里需要做幂等(避免因为重复消息造成的业务错乱)

复杂的混合异步业务调用

那么我们通过上面的分析可能联想到这样的问题?

本地先执行事务,执行成功了就发个消息过去,消费端拿到消息执行自己的事务
比如a,b,c a异步调用b,c, 如果b失败了,或者b成功,或者b超时,那么怎么用mq让他们最终一致呢?b失败就失败了,b成功之后给c发一个消息,b和c对a来讲都是异步的,且他们都是同时进行的话,而且需要a,b,c同时成功的情况,那么这种情况用mq怎么做

其实做法还是参照于本地事务的概念的。

  • 第一种情况:假设a,b,c三者都正常执行,那整个业务正常结束
  • 第二种情况:假设b超时,那么需要a给b重发消息(记得b服务要做幂等),如果出现重发失败的话,需要看情况,是终端服务,还是继续重发,甚至人为干预(所有的规则制定都需要根据业务规则来定)
  • 第三种情况:假设a,b,c三者之中的一个失败了,失败的服务利用MQ给其他的服务发送消息,其他的服务接收消息,查询本地事务记录日志,如果本地也失败,删除收到的消息(表示消息消费成功),如果本地成功的话,则需要调用补偿接口进行补偿(需要每个服务都提供业务补偿接口)。

注意事项

mq这里有个坑,通常只适用于只允许第一个操作失败的场景,也就是第一个成功之后必须保证后面的操作在业务上没障碍,不然后面失败了前面不好回滚,只允许系统异常的失败,不允许业务上的失败,通常业务上失败一次后面基本上也不太可能成功了,要是因为网络或宕机引起的失败可以通过重试解决,如果业务异常,那就只能发消息给a和c让他们做补偿了吧?通常是通过第三方进行补偿,ABC提供补偿接口,设计范式里通常不允许消费下游业务失败

上面的话我们该怎么理解呢,举个例子吧

比如A给B转账,A先自己扣钱,然后发了个消息,B这边如果在这之前销户了,那重试多少次也没用,只能人工干预

阿里在分布式事务采用的解决方式

阿里部分业务是用Mq实现了最终一致性,也有一部分业务用了tcc事务,但是tcc事务用的比较少,因为会侵染业务,开发成本比较高,如果体量不大的话直接用jta或mq支持事务就好,其实在分布式事务这一块还有一种最大努力型,也比较无脑的一种方式。

声明

以上观点均为个人总结,不代表完全正确。



作者:jsondream
链接:http://www.jianshu.com/p/716d3ec567c0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MQ分布式事务和feign加seata实现分布式事务有一些区别。 首先,MQ分布式事务是通过消息队列实现的。它的作用是解耦、异步、削峰,实现分布式事务最终一致性MQ分布式事务是一种柔性事务的解决方案,适用于高并发场景。在MQ分布式事务,事务参与者将事务消息发送到消息队列,消息队列再将消息异步分发给事务的其他参与者,各个参与者根据消息处理结果来决定是否提交或回滚事务。 而feign加seata是另一种实现分布式事务的方式。Feign是一种轻量级的、声明式的HTTP客户端,可以方便地实现服务之间的远程调用。而seata是一个开源的分布式事务解决方案,它提供了一套完整的分布式事务管理功能。在使用feign加seata实现分布式事务时,可以使用seata提供的分布式事务管理器来保证各个服务之间的事务一致性。 总的来说,MQ分布式事务和feign加seata实现分布式事务都可以实现分布式事务一致性,但是它们的实现方式和适用场景有所不同。MQ分布式事务适用于高并发场景,而feign加seata适用于服务之间的远程调用。具体使用哪种方式取决于实际的业务需求和场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [seata与MQ分布式事务区别](https://blog.csdn.net/qq_39761320/article/details/109730112)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [分布式事务解决方案及Seata 1.6.1案例](https://blog.csdn.net/qq_42665745/article/details/130805466)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值