方案 |
解决思路 |
适用场景 |
说明 |
本地事务 |
- 基于数据库的ACID理论
- 基于undo、redo日志记录
- undo日志实现回滚、redo日志实现commit场景异常的恢复
|
- 传统单体架构
- 分布式事务要求不高的场景
|
- 分布式系统场景出现问题怎么办?
- 日志记录--监控告警–人工干预修复
- 问题溯源,例如:维修工单能够建立,可是维修费用调用失败致使整个事务回滚
- 可能维修费用自身问题,如性能压力过大致使请求时,触发调用失败回滚
- 可能维修费用操做依据成功了,可是返回
|
两阶段提交 |
- 基于XA协议,依赖TM、RM的交互,依赖数据库的能力
- TM存在单点故障,锁资源占用时间较长
|
- 面向多数据源或者分布式数据库设计(XA本质是TM与RM之间的规范)
- 适用于多数据源的架构
- Mycat也实现了XA协议,一些公司的分布式事务使用该方案,可是应用层非微服务架构
- 适用于并发量不大,处理时间较短的核心交易业务场景
|
- XA协议:

|
三阶段提交 |
- 基于TCC协议
- 在数据库外部实现事务机制达到最终一致性
- 牺牲了应用的灵活性,须要提供Try、Confirm、Cancel的具体实现,且须要当心保证幂等操做
|
- 跨应用,但须要实现TCC接口,对已有系统侵入较大,适用于新系统
- 不强依赖数据库特性,TCC是一个通用的模型
- 参考实现:https://github.com/liuyangming/ByteTCC/
|
- TCC协议:

|
可靠消息模式 |
- 大事务转变为小事务,小事物之间的不一致经过额外的轮训任务进行补偿
-
-
可分为基于本地事件、基于外部事件两种模式
- 业务逻辑须要保证幂等性
|
- 适用于核心模块的改造,或者彻底基于消息驱动的架构,不然对已有系统入侵较大
- 另外,若是须要回滚,超过两个实务操做的场景比较复杂,因此这种场景须要遵照最终一致性原则,失败不会滚,直到补偿成功
- 依赖具有事务功能的消息系统或者数据库,如:RabbitMQ、Kafka、RocketMQ等
|
- 基于本地事件:

- 基于外部事件:

|
可靠消息变种 |
- 不依赖消息队列通讯,将消息队列的功能包装为Rest服务,屏蔽消息队列的接口
- 将基于可靠消息模式对架构和应用入侵的缺点下降
|
- 最大努力通知型
- 如支付宝的回调机制,能够设置指数时间重试,参考阿里实现:https://zhuanlan.zhihu.com/p/26114119
|
|
- 下游应用轮询
- 如微信的轮询机制,由下游应用本身保证一致性
|
|
SAGA方案 |
- 基于工做流的思路,原理:https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf
- 定义顺序操做、回滚操做的流程,交给事务协调器统一管理
- 一些应用框架实现了该方案,如CQRS框架Axonframework:https://github.com/AxonFramework/AxonFramework,又如华为servicecomb:https://github.com/apache/incubator-servicecomb-saga
|
- 应用方定义工做流,交给SAGA进行管理,虽然这种方案不火热,可是对应用入侵较小,且符合分层的设计原则,添加一个composite层单独实现须要分布式事务的流程便可
|
- SAGA工做流:

|
阿里GTS |
- 优化XA架构的路线,使用上与XA相似,业务入侵较小,添加注解
- GTS参考:https://zhuanlan.zhihu.com/p/32684212
- 仿GTS实现:https://github.com/wxbty/meepo
https://github.com/chenjy16/gts
- 与GTS相似的:https://github.com/codingapi/tx-lcn 看起来最成熟的开源方案
|
- 适用于阿里云方案,专线也能够接入使用,第三方系统遵循TCC的也能够接入
|
|
总结建议 |
- 若是非必要,不引入分布式事务,每一个微服务保证自身的高可用,基本可以保证数据的一致性,极端的状况除外。--事实上微服务的架构BAT十年前就在使用,没有分布式事务也同样,由于基础设施、每一个微服务自身可用性比较高,因此不须要引入更大的复杂性
- 若是必要,首先保证核心业务的数据一致性,好比交易业务,能够采用消息机制、最大努力通知、轮询机制的方案,他们的本质都是记帐,即便出了问题也有据可查--这部分通常借助第三方支付系统的能力便可知足
- 若是只是较少许的业务须要分布式事务特性,能够局部使用基于可靠消息的方案,参考:https://github.com/vvsuperman/coolmq,这种方案须要注意不少细节,理论上每一个环节均可能出现网络异常,都须要有相应的措施保障,好比:若是创建指数时间重试机制,下游服务接口须要保证幂等,该方案至关于业务本身负责维护一致性
- 若是大量业务须要分布式事务,也能够引入相似DelayMq的服务作解耦,利用该服务提供回调服务将服务链串联起来(消息中包含回调的Url、参数),可是下游的服务接口须要保证幂等性--PaaS平台能够提供相似的服务,参考:https://zhuanlan.zhihu.com/p/26114119。该方案须要可以接受部分代码的重构
- 若是大量业务须要分布式事务,能够引入相似GTS对业务入侵较小的框架,避免更新架构和代码,代码添加必要的注解便可,如:https://github.com/codingapi/tx-lcn --开源方案,建议通过测试以后谨慎上线,这个能力也能够研究下看看能不能作到PaaS平台
- 数据一致性是一个系统工程,仅仅在事务框架层面解决是不够的,还须要配套的规范措施--如请求RequestID、链路追踪、接口幂等、日志输出规范、关键日志记录规范等,出现问题能够快速定位,这部分的数据可让PaaS接管,提供链路服务、监控告警服务等
- 完善基础设施,下降网络问题的影响是重要前提。对于实际调用已经成功,返回时网络异常的问题,须要补偿机制--PaaS能够提供相似DelayMq的服务
- 完善应用的监控告警设施,如应用的API、访问次数、失败次数等监控,及时告警--PaaS能够提供应用的实时监控告警能力
|