Spring Cloud 分布式事务管理

Spring Cloud 分布式事务管理

在微服务如火如荼的状况下,愈来愈多的项目开始尝试改形成微服务架构,微服务即带来了项目开发的方便性,又提升了运维难度以及网络不可靠的几率.java

@[toc]
在说微服务的优缺点时,有对比才会更加明显,首先说一下单体式结构mysql

单体式架构

在单体式架构中,系统一般采用分层架构模式(MVC),持久化层、表示层,业务逻辑层。架构主要存在如下问题:git

  1. 系统内部互相访问,耦合紧密致使难以维护;
  2. 各业务领域须要采用相同的技术栈,难以快速应用新技术(例如使用SSH很难向SSM改造);
  3. 对系统的任何修改都必须整个系统一块儿从新部署/升级;
  4. 在系统负载增长时,难以进行水平扩展;
  5. 当系统中一处出现问题,会影响整个系统;

为了克服以上缺点,微服务架构应运而生。微服务,又叫微服务架构。微服务就是一些协同工做的小而自治的服务.github

微服务架构

优势:

1. 技术异构性spring

在不一样的服务中,可使用不一样的技术来各自开发,只要保证服务间能相互协做便可sql

2. 弹性数据库

当微服务中的某一个服务不可用时,不会影响整个系统,只会影响相关功能不可用编程

3. 扩展api

易于扩展,使用小的多个服务,更加易于扩展新的功能服务器

4. 简化部署

某个服务的更新部署,不须要从新部署整个应用

5. 可组合

经过组合多个服务,能够提供一些新的功能

6. 可替代

由于每一个微服务都比较小,从新实现某一个服务或者直接删除该服务都是可操做的

缺点:

1. 复杂度高

微服务间经过REST、RPC等形式交互,相对于单体模式,须要考虑被调用方故障、过载、消息丢失等各类异常状况,代码逻辑更加复杂。

对于微服务间的事务性操做,由于不一样的微服务采用了不一样的数据库,将没法利用数据库自己的事务机制保证一致性,须要引入二阶段提交等技术。

同时,在微服务间存在少部分共用功能但又没法提取成微服务时,各个微服务对于这部分功能一般须要重复开发,或至少要作代码复制,以免微服务间的耦合,增长了开发成本。

2. 运维复杂

在采用微服务架构时,系统由多个独立运行的微服务构成,须要一个设计良好的监控系统对各个微服务的运行状态进行监控。运维人员须要对系统有细致的了解才对够更好的运维系统。

3. 影响性能

相对于单体架构,微服务的间经过REST、RPC等形式进行交互,通讯的时延会受到较大的影响。

分布式事务的引入

正如上面所说

对于微服务间的事务性操做,由于不一样的微服务采用了不一样的数据库,将没法利用数据库自己的事务机制保证一致性,须要引入二阶段提交等技术。

在单体项目中,很容易作到事务控制,而在多个服务之间很难实现

假设服务调用以下:

这里写图片描述

A B C D 的事务均在各个服务控制,如何作到,统一协调,保证数据的一致性?

分布式事务解决方案

基于XA协议的两阶段提交

XA是一个分布式事务协议,由提出。XA中大体分为两部分:事务管理器和本地资源管理器。其中本地资源管理器每每由数据库实现,好比Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器做为全局的调度者,负责各个本地资源的提交和回滚。XA实现分布式事务的原理以下:
第一阶段:

Tuxedo

第二阶段:
这里写图片描述

总的来讲,XA协议比较简单,并且一旦商业数据库实现了XA协议,使用分布式事务的成本也比较低。可是,XA也有致命的缺点,那就是性能不理想,特别是在交易下单链路,每每并发量很高,XA没法知足高并发场景。XA目前在商业数据库支持的比较理想,在mysql数据库中支持的不太理想,mysql的XA实现,没有记录prepare阶段日志,主备切换回致使主库与备库数据不一致。许多nosql也没有支持XA,这让XA的应用场景变得很是狭隘。

消息事务+最终一致性

所谓的消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操做成功成功而且对外发消息成功,要么二者都失败,开源的RocketMQ就支持这一特性.

该方案采用最终一致的,牺牲了一致性,换来了性能的大幅度提高。存在形成数据不一致的风险

TCC编程模式

所谓的TCC编程模式,也是两阶段提交的一个变种。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操做。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,若是更新订单失败,则进入Cancel阶段,会去恢复库存。总之,TCC就是经过代码人为实现了两阶段提交,不一样的业务场景所写的代码都不同,复杂度也不同,所以,这种模式并不能很好地被复用。

具体实现

LCN

https://github.com/codingapi/...
LCN分布式事务框架的核心功能是对本地事务的协调控制,框架自己并不建立事务,只是对本地事务作协调控制。所以该框架与其余第三方的框架兼容性强,支持全部的关系型数据库事务,支持多数据源,支持与第三方数据库框架一块使用(例如 sharding-jdbc),在使用框架的时候只须要添加分布式事务的注解便可,对业务的侵入性低。LCN框架主要是为微服务框架提供分布式事务的支持,在微服务框架上作了进一步的事务机制优化,在一些负载场景上LCN事务机制要比本地事务机制的性能更好,4.0之后框架开方了插件机制可让更多的第三方框架支持进来

目前 LCN为 4.1 版本

主要特色:

  • 支持各类基于spring的db框架
  • 兼容SpringCloud、Dubbo、motan
  • 使用简单,低依赖,代码彻底开源
  • 基于切面的强一致性事务框架
  • 高可用,模块能够依赖RPC模块作集群化,TxManager也能够作集群化
  • 支持本地事务和分布式事务共存
  • 支持事务补偿机制,增长事务补偿决策提醒

采用强一致性方案,事务要不所有成功,要不所有失败,保证了事务的一致性,代码简单,原有项目只需引入相关 jar 包,并在须要参与的事务的方法添加注解便可,节省了代码改形成本.

Spring Cloud示例:

添加依赖

<properties>
   <lcn.last.version>4.1.0</lcn.last.version>
</properties>

<dependency>
    <groupId>com.codingapi</groupId>
    <artifactId>transaction-springcloud</artifactId>
    <version>${lcn.last.version}</version>
</dependency>

<dependency>
   <groupId>com.codingapi</groupId>
   <artifactId>tx-plugins-db</artifactId>
   <version>${lcn.last.version}</version>
</dependency>

在须要执行的事务上添加注解

@Override
@TxTransaction(isStart = true)
@Transactional
public int save() {
}

其中 @TxTransaction(isStart = true)lcn 事务控制注解,其中isStart = true 表示该方法是事务的发起方例如,服务A 须要调用服务B,服务B 须要调用服务C,此时 服务A为服务发起方,其他为参与方,参与方只需@TxTransaction 便可

在测试时须要将 事务管理服务启动 txManager, 具体示例参看:https://www.txlcn.org

ByteTCC

https://github.com/liuyangmin...

ByteTCC是一个基于TCC(Try/Confirm/Cancel)机制的分布式事务管理器。兼容JTA,能够很好的与EJB、Spring等容器(本文档下文说明中将以Spring容器为例)进行集成。

ByteTCC特性
一、支持Spring容器的声明式事务管理;
二、支持普通事务、TCC事务、业务补偿型事务等事务机制;
三、支持多数据源、跨应用、跨服务器等分布式事务场景;
四、支持长事务;
五、支持dubbo服务框架;
六、支持spring cloud;

该实现方式,须要在业务层编写对应的 tcc(Try/Confirm/Cancel) 方法,开发须要必定的成本,同时某些业务可能没法保证数据可回滚

查看示例: https://github.com/liuyangmin...

参考:

  1. https://github.com/codingapi/...
  2. https://github.com/liuyangmin...
  3. 微服务设计(Sam Newman)
若是你喜欢就关注一下吧. 之后会写一下咱们公司在使用Spring Cloud 中遇到的问题和一些经验

这里写图片描述

相关文章
相关标签/搜索