分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?
作者:何明璐
链接:http://www.zhihu.com/question/29483490/answer/98237582
来源:知乎
著作权归作者所有,转载请联系作者获得授权。
可以设想一个最简单的分布式事务场景,对于跨银行的转账操作,该操作涉及到调用两个异地的Service服务,一个是本地提供的取款服务,一个是目标银行提供的存款服务,该两个服务本身无状态且独立,构成一个完整的事务。对于事务的处理初步分析:
事务补偿机制
事务补偿即在事务链中的任何一个正向事务操作,都必须存在一个完全符合回滚规则的可逆事务。如果是一个完整的事务链,则必须事务链中的每一个业务服务或操作都有对应的可逆服务。对于Service服务本身无状态,也不容易实现前面讨论过的通过DTC或XA机制实现的跨应用和资源的事务管理,建立跨资源的事务上下文。因此也较难以实现真正的预提交和正式提交的分离。
在这种情况下以上面例子来说,首先调用取款服务,完全调用成功并返回,数据已经持久化。然后调用异地的存款服务,如果也调用成功,则本身无任何问题。如果调用失败,则需要调用本地注册的逆向服务(本地存款服务),如果本地存款服务调用失败,则必须考虑重试,如果约定重试次数仍然不成功,则必须log到完整的不一致信息。也可以是将本地存款服务作为消息发送到消息中间件,由消息中间件接管后续操作。
在上面方式中可以看到需要手工编写大量的代码来处理以保证事务的完整性,我们可以考虑实现一个通用的事务管理器,实现事务链和事务上下文的管理。对于事务链上的任何一个服务正向和逆向操作均在事务管理和协同器上注册,由事务管理器接管所有的事务补偿和回滚操作。
基于消息的最终一致性
在这里首先要回答的是我们需要时实时一致性还是最终一致性的问题,如果需要的是最终一致性,那么BASE策略中的基于消息的最终一致性是比较好的解决方案。这种方案真正实现了两个服务的真正解耦,解耦的关键就是异步消息和消息持久化机制。
还是以上面的例子来看。对于转账操作,原有的两个服务调用变化为第一步调用本地的取款服务,第二步发送异地取款的异步消息到消息中间件。如果第二步在本地,则保证事务的完整性基本无任何问题,即本身就是本地事务的管理机制。只要两个操作都成功即可以返回客户成功。
由于解耦,我们看到客户得到成功返回的时候,如果是上面一种情况则异地卡马上就能查询账户存款增加。而第二种情况则不一定,因为本身是一种异步处理机制。消息中间件得到消息后会去对消息解析,然后调用异地银行提供的存款服务进行存款,如果服务调用失败则进行重试。
异地银行存款操作不应该长久地出现异常而无法使用,因此一旦发现异常我们可以迅速的解决,消息中间件中异常服务自然会进行重试以保证事务的最终一致性。这种方式假设问题一定可以解决,在不到万不得已的情况下本地的取款服务一般不进行可逆操作。
在本地取款到异地存款两个服务调用之间,会存在一个真空期,这段时间相关现金不在任何一个账户,而只是在一个事务的中间状态,但是客户并不关心这个,只要在约定的时间保证事务最终的一致性即可。
关于等幂操作的问题
重复调用多次产生的业务结果与调用一次产生的业务结果相同,简单点讲所有提供的业务服务,不管是正向还是逆向的业务服务,都必须要支持重试。因为服务调用失败这种异常必须考虑到,不能因为服务的多次调用而导致业务数据的累计增加或减少。
关于是否可以补偿的问题
在这里我们谈的是多个跨系统的业务服务组合成一个分布式事务,因此在对事务进行补偿的时候必须要考虑客户需要的是否一定是最终一致性。客户对中间阶段出现的不一致的承受度是如何的。
在上面的例子来看,如果采用事务补偿机制,基本可以是做到准实时的补偿,不会有太大的影响。而如果采用基于消息的最终一致性方式,则可能整个周期比较长,需要较长的时间才能给得到最终的一致性。比如周六转款,客户可能下周一才得到通知转账不成功而进行了回退,那么就必须要考虑客户是否能给忍受。
其次对于前面讨论,如果真正需要的是实时的一致性,那么即使采用事务补偿机制,也无法达到实时的一致性。即很可能在两个业务服务调用中间,客户前台业务操作对持久化的数据进行了其它额外的操作。在这种模式下,我们不得不考虑需要在数据库表增加业务状态锁的问题,即整个事务没有完整提交并成功前,第一个业务服务调用虽然持久化在数据库,但是仍然是一个中间状态,需要通过业务锁来标记,控制相关的业务操作和行为。但是在这种模式下无疑增加了整个分布式业务系统的复杂度。
关于SOA分布式事务情况参考:http://wenku.baidu.com/view/be946bec0975f46527d3e104.html
分布式服务的事务如何处理?比如dubbo,服务与服务之间的事务怎么处理比较好,现在有没有开源的解决方案?的更多相关文章
- Dubbo入门到精通学习笔记(十):dubbo服务集群 、Dubbo分布式服务子系统的划分、Dubbo服务接口的设计原则
文章目录 dubbo服务集群 Dubbo服务集群部署 Dubbo服务集群容错配置--集群容错模式 1.Failover Cluster 失败自动切换,当出现失败,重试其它服务器.`(缺省) 通常用于读 ...
- 精华【分布式、微服务、云架构、dubbo+zookeeper+springmvc+mybatis+shiro+redis】分布式大型互联网企业架构!
平台简介 Jeesz是一个分布式的框架,提供项目模块化.服务化.热插拔的思想,高度封装安全性的Java EE快速开发平台. Jeesz本身集成Dubbo服务管控.Zookeeper注册中心.Redis ...
- 【分布式架构】“spring cloud”与“dubbo”微服务的对比
秉承站在巨人的肩膀上,同时我也不想重复制造轮子,我发现了一系列关于“分布式架构”方面,我需要,同时能够解决我的一些疑惑.问题的博客,转载过来,原文链接: http://blog.csdn.net/ ...
- 分布式服务框架选型:面对Dubbo,阿里巴巴为什么选择了HSF?
转载:http://www.sohu.com/a/141490021_268033 阿里巴巴集团内部使用的分布式服务框架 HSF(High Speed Framework,也有人戏称“好舒服”)已经被 ...
- 【推荐】微服务分布式企业框架Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis
摘要: 主要定位于互联网企业架构,已内置企业信息化系统的基础功能和高效的代码生成工具,包括:系统权限组件.数据权限组件.数据字典组件.核心工具 组件.视图操作组件.工作流组件.代码 ...
- 分布式的几件小事(六)dubbo如何做服务治理、服务降级以及重试
1.服务治理 服务治理主要作用是改变运行时服务的行为和选址逻辑,达到限流,权重配置等目的. ①调用链路自动生成 一个大型的分布式系统,会由大量的服务组成,那么这些服务之间的依赖关系和调用链路会很复杂, ...
- 传统保险企业基于 Dubbo 的微服务实践
本文整理自中国人寿保险(海外)股份有限公司深圳中心技术总监家黄晓彬在 Dubbo 社区开发者日深圳站的现场分享. 中国人寿保险(海外)股份有限公司负责香港.澳门.新加坡和印尼的业务开发,和国内业务不同 ...
- Dubbo介绍和服务架构分析
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成.使用zookeeper作为服务的注册中心,对外提供服务 ...
- 服务发现与负载均衡 dubbo zk原理
服务发现与负载均衡 拓展阅读 : dubbo 原理概念图 2016-03-03 杜亦舒 性能与架构 性能与架构 性能与架构 微信号 yogoup 功能介绍 网站性能提升与架构设计 内容整理自文章“实施 ...
随机推荐
- StringBuilder基本用法
//StringBuilder用法 public class StringBuilderTest { public static void main(String[] args) { StringBu ...
- Effective C++笔记(三):资源管理
参考:http://www.cnblogs.com/ronny/p/3745098.html 资源:动态分配的内存.文件描述器.互斥锁.图形界面中的字型与笔刷.数据库连接以及网络sockets等, ...
- Java学习(一)Scanner报错java.util.NoSuchElementException
我在一个方法A中使用了Scanner的 Scanner input=new Scanner(System.in),随后又将其关闭了,因为Eclipse里面你若不关闭,他会有一个warning:Reso ...
- csu 最优对称路径(bfs+记忆化搜索)
1106: 最优对称路径 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 371 Solved: 77[Submit][Status][Web Boar ...
- gym101431B
以此纪念我都快忘了的后缀自动机(捂脸) 不过这题有两种做法: 用后缀自动机,先把原串再接遍中间加入特殊连接字符再把原串反接两遍,对这个新构造出的串做后缀自动机.(或者直接建立广义后缀自动机) 下面只要 ...
- Java虚拟机四:垃圾回收算法与垃圾收集器
在Java运行时的几个数据区域中,程序计数器,虚拟机栈,本地方法栈3个区域随着线程而生,随线程而灭,因此这几个区域的内存分配和回收具有确定性,不需要过多考虑垃圾回收问题,因为方法结束或者线程结束时,内 ...
- linux下安装nodejs及linux下解压tar.xz文件
1.下载nodejs的安装包 2.解压该文件 在linux下,大部分情况下不能直接解压tar.xz的文件. 需要用xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然 ...
- 转:XSS知识大总结
转:https://www.jianshu.com/p/75a3d9332b8c XSS知识大总结 2016.10.28 21:05* 字数 1332 阅读 961评论 2喜欢 13 XSS-即Cro ...
- 转:Meltdown Proof-of-Concept
转:https://github.com/IAIK/meltdown Meltdown Proof-of-Concept What is the difference between Meltdown ...
- pycharm中在andconda环境中配置pyqt环境
一般在andconda环境中,自带pyqt5 在pip install pyqt5之后,需要安装pyqt5_tools. 对于pycharm需要配置pyqt Designer和pyqt UIC. De ...