写在前面:

由于工作需要,公司的微服务项目需解决分布式事务的问题,且由我进行分布式事务框架搭建和整合工作。

那么借此机会好好的将解决分布式事务的内容进行整理一下。这边公司分布式事务框架选型是LCN框架(以后肯定会升级成seata)。

我整理的大纲如下:

1 CAP定律和BASE理论

  有人问,为什么需要了解这个,这个其实是分布式事务基于的理论依据,所以需要了解一下。

1.1 CAP定律

  这个定理的内容是指的是在一个分布式系统中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。

(一)一致性(C)

  在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)

(二)可用性(A)

  在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)

(三)分区容错性(P)

  以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

(四)总结一下

  以上可以知道分区容错性(P)主要代表网络波动产生的错误,这是不可避免的,且这个三个模式不可兼得,所以目前就只有两种模式:CP和AP模式。

  其中CP表示遵循一致性原则,但不能保证高可用性,其中zookeeper作为注册中心就是采用CP模式,因为zookeeper有过半节点不可以的话整个zookeeper将不可用。

  AP表示遵循于可用性原则,例如Eureka作为注册中心用的是AP模式,因为其为去中心化,采用你中有我我中有你的相互注册方式,只要集群中有一个节点可以使用,整个eureka服务就是可用的,但可能会出现短暂的数据不一致问题。

1.2 BASE理论

BASE是Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的缩写。BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结, 是基于CAP定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。

(一)基本可用

  基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性,注意,这绝不等价于系统不可用。

  比如:响应时间上的损失。正常情况下,一个在线搜索引擎需要在0.5秒之内返回给用户相应的查询结果,但由于出现故障,查询结果的响应时间增加了1~2秒。

  系统功能上的损失:正常情况下,在一个电子商务网站上进行购物的时候,消费者几乎能够顺利完成每一笔订单,但是在一些节日大促购物高峰的时候,由于消费者的购物行为激增,为了保护购物系统的稳定性,部分消费者可能会被引导到一个降级页面。

(二)软状态

  软状态指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。

(三)最终一致性

  最终一致性强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

2 了解分布式事务

2.1 分布式事务产生的背景

  在分布式产生之前,互联网公司的项目都是传统的单体项目,整个项目都共用了一个数据源,那么进行业务执行对数据库进行操作的时候,不会产生这种事务不一致问题,因为是同一个数据源用的一个本地事务。

  但随着我们架构的演变,从单体架构到分布式架构到SOA架构项目再到如今公司采用的微服务架构,我们对服务进行了业务拆分,那么数据源也被拆分,一般微服务项目是一个服务对应一个数据源。

  那么在这种架构下,每个服务都有自己独立的数据源有自己的本地事务,从而便会产生分布式事务,可能造成服务间数据不一致问题。

2.2 不同架构体系下解决事务的问题

(一)单体架构(单数据源)

  在单体的项目中,多个不同业务逻辑都是在同一个数据源中实现事务管理,是不存在分布式事务的问题,因为同一数据源的情况下都是采用事务管理器,相当于每个事务管理器对应一个数据源。

(一)单体架构(多数据源)

  在单体的项目中,有多个不同的数据源,每个数据源中都有自己独立的事务管理器,互不影响,那么这时候也会存在多数据源事务管理:解决方案jta+ Atomikos。

(一)分布式/微服务架构

  在分布式/微服务架构,每个服务都有自己独立的数据源和事务管理器,那么在这种情况下如果有业务要进行RPC远程调用的时候,那就必然可能产生分布式事务。目前主要解决方案有:MQ、LCN、Seata等方案。

LCN解决分布式事务

3.1 了解LCN

3.1.1 LCN背景

  LCN框架在2017年6月份发布第一个版本,从开始的1.0,已经发展到了5.0版本。

  LCN名称是由早期版本的LCN框架命名,在设计框架之初的1.0 ~ 2.0的版本时框架设计的步骤是如下,各取其首字母得来的LCN命名。

  5.0以后由于框架兼容了LCN、TCC、TXC三种事务模式,为了避免区分LCN模式,特此将LCN分布式事务改名为TX-LCN分布式事务框架。

3.1.2 LCN定位

TX-LCN定位于一款事务协调性框架,框架其本身并不操作事务,而是基于对事务的协调从而达到事务一致性的效果。(LCN不生产事务,它只是事务的搬运工...woc这有点像农夫山泉的文案)

3.2 LCN分布式事务原理(自己理解的,白话文通俗易懂)

(上图来源官网)

  1) 首先我们的lcn协调者(TM)会和lcn客户端(TC)通过引入的netty一直保持着长连接(持续监听)。

  2) 当请求的发起方(调用方)进入接口业务之前,会通过AOP技术进到@LcnTransaction注解中去LCN协调者那边生成注册一个全局的事务组Id(groupId)。

  3) 当发起方(调用方)通过rpc调用参与方(被调用方)的时候,lcn重写了Feign客户端,会从ThreadLocal中拿到该事务组Id(groupId),并将该事务组Id设置到请求头中。

  4) 参与方(被调用方)在请求头中获取到了这个groupId的时候,lcn会标识该服务为参与方并加入到该事务组,并会被lcn代理数据源,当该服务业务逻辑执行完成后,进行数据源的假关闭,并不会真正的提交或回滚当前服务的事务。

  5) 当发起方执行完全部业务逻辑的时候,如果无异常会告知lcn协调者,lcn协调者再分别告诉该请求链上的所有参与方可以提交了,再进行真正的提交。若发起方调用完参与方后报错了,也会告知lcn协调者,lcn协调者再告知所有的参与方进行真正的回滚操作,这样就解决了分布式事务的问题。

3.3 LCN本地环境部署

3.3.1 本地部署注册中心

  注册中心是微服务中最为重要的一个组件,提供了服务间在调用时需要的一些ip和端口等列表信息。

  我这边采用nacos作为注册中心,具体如何一分钟快速搭建本地nacos可参见:https://nacos.io/zh-cn/docs/quick-start.html 注册中心的部署略过不做详细的说明。搭建好nacos后,访问127.0.0.1:8848/nacos进行访问(账号密码默认为nacos),出现如下界面即完成了nacos本地的搭建。

3.3.2 本地部署协调者TM环境

  在部署TX-LCN中有遇到问题或想查看部署详细的操作可以访问如下地址:http://www.txlcn.org/zh-cn/docs/start.html 。

  1) 我们要去github中先将tx-lcn的源码下载下来,这边我们选择的是5.0.2的版本,github下载源码地址:https://github.com/codingapi/tx-lcn/releases

  2) 创建相应的数据库表,先创建MySQL数据库, 名称为: tx-manager,再创建数据库表t_tx_exception。

CREATE TABLE `t_tx_exception`  (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`group_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`unit_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`mod_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`transaction_state` tinyint(4) NULL DEFAULT NULL,
`registrar` tinyint(4) NULL DEFAULT NULL,
`remark` varchar(4096) NULL DEFAULT NULL,
`ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 未解决 1已解决',
`create_time` datetime(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 

  3) 打开我们下好的源码,找到txlcn-tm模块,修改其配置文件application.properties,具体修改的内容根据自己业务而定,官方也有相应配置内容,但需要注意首次运行要将配置文件的这段设置为create:spring.jpa.hibernate.ddl-auto=create。

  4) 准备将txlcn-tm模块打包成jar包,先执行打包命令: mvn clean package -Dmaven.test.skip=true ,打包完成后可以在模块中看到出现了jar包。

  5) 开始对jar包进行运行,进入到target目录,执行命令启动jar包:java -jar txlcn-tm-5.0.2.RELEASE.jar

  6) 运行成功后可以看到tomcat启动成功。

  7) 访问控制台的端口为7919,默认密码codingapi。

  至此,TM部署并启动完成。

3.3.3 本地配置客户端TC环境

  TC就是我们的客户端,也就是我们的微服务,配置相对简单如下:

  1) 引入相关依赖,其中一个是lcn核心包,一个是建立长连接的netty包。

<dependency>
<groupId>com.codingapi.txlcn</groupId>
<artifactId>txlcn-tc</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.codingapi.txlcn</groupId>
<artifactId>txlcn-txmsg-netty</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>

  2) 配置yml文件,设置服务连接到lcn服务。(注意下lcn控制台是7970,这个8070是lcn通讯端口号)

tx-lcn:
client:
manager-address: 127.0.0.1:8070
logger:
enabled: true

  3) 引入依赖并配置好yml文件后,在服务的启动类上添加@EnableDistributedTransaction注解,开启分布式事务。

  4) 在业务的方法上面添加注解@LcnTransaction和@Transactional,如下图。

  5) 做好这些配置后,开始启动项目,启动成功项目后可以在lcn控制台看到相应的服务列表,能够看到则说明服务已经实现了对lcn事务协调者管理器的注册。

  看到服务都能够成功注册进TM后,便全部完成TX-LCN本地环境的搭建,后续可以开始测试自己的业务代码是否解决了分布式事务的问题。

LCN解决分布式事务原理解析+项目实战(原创精华版)的更多相关文章

  1. 【分布式事务】spring cloud集成lcn解决分布式事务

    参考地址:https://blog.csdn.net/u010882691/article/details/82256587 参考地址:https://blog.csdn.net/oyh1203/ar ...

  2. MQ关于实现最终一致性分布式事务原理解析

    本文讲述阿里云官方文档中关于通过MQ实现分布式事务最终一致性原理 概念介绍 事务消息:消息队列 MQ 提供类似 X/Open XA 的分布式事务功能,通过消息队列 MQ 事务消息能达到分布式事务的最终 ...

  3. RabbitMQ解决分布式事务

    案例:经典案例,以目前流行点外卖的案例,用户下单后,调用订单服务,让后订单服务调用派单系统通知送外卖人员送单,这时候订单系统与派单系统采用MQ异步通讯. RabbitMQ解决分布式事务原理: 采用最终 ...

  4. 解决分布式事务基本思想Base和CPA理论、最终一致性|刚性事务、柔性事务

    在学习解决分布式事务基本思路之前,大家要熟悉一些基本解决分布式事务概念名词比如:CAP与Base理论.柔性事务与刚性事务.理解最终一致性思想,JTA+XA.两阶段与三阶段提交等. 如何保证强一致性呢? ...

  5. 使用kafka消息队列解决分布式事务(可靠消息最终一致性方案-本地消息服务)

    微服务框架Spring Cloud介绍 Part1: 使用事件和消息队列实现分布式事务 本文转自:http://skaka.me/blog/2016/04/21/springcloud1/ 不同于单一 ...

  6. 分布式事务(3)---RocketMQ实现分布式事务原理

    分布式事务(3)-RocketMQ实现分布式事务原理 之前讲过有关分布式事务2PC.3PC.TCC的理论知识,博客地址: 1.分布式事务(1)---2PC和3PC原理 2.分布式事务(2)---TCC ...

  7. 【分布式事务】使用atomikos+jta解决分布式事务问题

    一.前言 分布式事务,这个问题困惑了小编很久,在3个月之前,就间断性的研究分布式事务.从MQ方面,数据库事务方面,jta方面.近期终于成功了,使用JTA解决了分布式事务问题.先写一下心得,后面的二级提 ...

  8. springboot整合多数据源解决分布式事务

    一.前言        springboot整合多数据源解决分布式事务.             1.多数据源采用分包策略              2.全局分布式事务管理:jta-atomikos. ...

  9. 搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务

    搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 初步认识RocketMQ的核心模块 rocketmq模块 rocketmq-broker:接受生产者发来的消息并存储(通过调用rocke ...

随机推荐

  1. 图形学创世纪——写在SIGGRAPH 40年的边上

    40年的边上" title="图形学创世纪--写在SIGGRAPH 40年的边上"> 前言: SIGGRAPH是由ACM SIGGRAPH(美国计算机协会计算机图形 ...

  2. 网络TCP/IP分层、子网掩码等基本概念

    一.TCP/IP分层: OSI七层网络模型 TCP/IP四层概念模型 对应网络协议 应用层(Application) 应用层 HTTP.TFTP, FTP, NFS, WAIS.SMTP 表示层(Pr ...

  3. Linux(Centos7.X ) 配置Java 环境变量

    前提条件:上传Jdk 文件到Linux服务器上. tar -zxvf jdk-8u111-linux-x64.tar.gz 修改 /etc/profile 在打开的文件末尾添加如下内容: export ...

  4. RxSwift学习笔记之Subject

    本文为原创文章,转载请标明出处 AsyncSubject 一个AsyncSubject只在原始Observable完成后,发射来自原始Observable的最后一个值.它会把这最后一个值发射给任何后续 ...

  5. JavaScript中对象数组去重方法

    在一次对后端返回的对象数组的操作时想通过indexOf()或者includes()的方法来实现对对象数组的去重但是行不通,因为用indexOf()返回的都是-1,一下记录两种对象数组(更具指定属性)去 ...

  6. 吴裕雄--天生自然KITTEN编程:对话

  7. 从零开始实现基于微信JS-SDK的录音与语音评价功能

    最近接受了一个新的需求,希望制作一个基于微信的英语语音评价页面.即点击录音按钮,用户录音说出预设的英文,根据用户的发音给出对应的评价.以下是简单的Demo: ![](reecode/qrcode.pn ...

  8. 瑞士一苹果店内iPhone突然爆炸致7人入院,iPhone还值得买吗?

    与国产手机高歌猛进态势呈现"最萌发展差"的,是以三星.苹果为代表的海外手机厂商在过去一年的疲态.数据显示,2017年小米手机产量较2016年增长幅度达76%,OPPO和vivo则分 ...

  9. scrapy爬虫框架教程(二)-- 爬取豆瓣电影

    前言 经过上一篇教程我们已经大致了解了Scrapy的基本情况,并写了一个简单的小demo.这次我会以爬取豆瓣电影TOP250为例进一步为大家讲解一个完整爬虫的流程. 工具和环境 语言:python 2 ...

  10. Python-控制语句及函数

    if-elif-else for while 函数 函数定义 空函数 pass 返回多个值 可变参数 * 关键字参数 ** 控制语句 if - elif - else 比如,输入用户年龄,根据年龄打印 ...