分布式事务学习有感

本篇文章仅限于个人学习 引用文献出处将落款至文章末尾 

以问题为导向 搞懂 是什么 怎么实现 出现问题怎么用它解决 

偶然兴趣接触到分布式事务和微服务 下篇做微服务

问题

提到分布式事务 什么是事务 什么是分布式系统 为什么会有分布式事务 分布式事务定义? 分布式是如何部署在项目的 分布式在实际应用里 到底是本机还是云服务?(后续是个人在面试过程中被提及的)

什么是事务?

事务在我看来 是保证对某数据进行读写操作时 因为并发操作 数据产生不一致而出现脏读 不可重复读 幻读的问题 

事务采用 ACID 解决脏读的问题 

A Atomic要求都是原子性的操作 (要么操作全部成功 要么操作全部失败)

C Consistent 一致性 事务执行前后数据库从一个一致性状态变为另一个一致性状态

I Isolate 隔离性 数据可能在多线程情况下 有并发的操作 需要保证操作间的隔离 防止数据不一致

D Duration 持久性 redolog把数据按照刷盘机制把数据持久化到磁盘里永久留存

常见的事务可能有 spring 框架的 @transaciton 数据库的 ACID 

数据库的事务是通过 start transaction 中途进行dml操作 并且commit来实现的 

什么是分布式系统

顾名思义 就是多个系统(多个服务/节点)组合为一个大系统(非物理) 子系统部署在虚拟机/物理机上 再通过网络通信(rpc) 最终实现业务

先说单机情况

先从请求发送的角度来看

从 java后端角度  用户点击前端按钮发送请求 请求先经过防火墙 防火墙根据规则需要拦截恶意请求 安全请求会进入系统 nginx 再根据nginx的预设配置规则完成请求转发 如果是获取前端页面 请求(浏览器输入网址) nginx匹配 网址 前端服务器地址 映射规则 

把请求转发到对应前端服务器 服务器再返回前段界面资源 

如果说业务操作 nginx会识别请求路径特折 /api 按照规则发给api网关 

API网关服务路由 收到nginx请求后分两步定位后端

网关先按照配置通过请求路径确定服务类型 再根据注册中心注册的所有后端服务的服务名与地址的映射(服务启动会自动注册)网关根据目标服务类型从注册中心获取该服务的具体地址 并且把请求转发到后端服务 

后端收到请求后 通过@controller下的控制层来执行业务逻辑 如果涉及到sql 还需要mybatis执行sql和数据库交互 获取/修改数据 

业务完成后按照 后端 API网关 Nginx 前端的路径返回 最后在前端返回结果

如果大量的请求把这条链路上所有可以承受的请求数全部填满 超过单个系统阈值

系统就会崩溃 会  1.不可用!

这是最直观的感受 换个角度再思考全链路 模拟在单机 高并发场景下

怎么优化? 我可以增加nginx服务器 做负载均衡 防止一个nginx服务崩了 也可以在后端这里 做线程池 异步处理队列任务 但是线程资源总有耗尽的时候 触发拒绝策略 响应也会延迟 面对单机还是不合适 在数据库这里可以用主从模式 主库写从库读的方式也能缓解一定的请求流量 但是读写压力巨大 锁竞争激烈 也可以用 redis 这种分布式缓存

但是 容易因为单机环境下qps上限导致redis的利用率比较低 

前后链路这么长 一定会有时间上的响应差异 也就是会有在操作数据时 因为时差而产生数据不一致情况 需要保证单个系统的 2.前后操作一致性!

但是如果在多节点(多个系统)协同工作 这种数据一致性要求会更高 所以分布式系统也需要保证一致性

同时 单机情况下 某个关键步骤down了 而你又是单个服务器 整条链路不可用 一直报错也是不可以的 所以 分布式系统为了解决这种单点故障 选择了多个节点 即使出现单点故障也不影响其他节点 不能导致整个服务因为某节点挂了而导致分布式系统整套服务雪崩  这就是分布式系统的故障独立

也叫做 分区容错性 

在单机情况下 各个组件之间也是通过网络通信实现(io nio epoll等等)与协议(tcp)还有ip(dns)来实现信息传递和业务交互 扩展到多个子系统 也需要网络通信协议来实现(rpc/http)

同时 在多个小系统之间也需要进行通信 所以因为网络延迟而造成的消息阻塞 也会导致不一致

总结下分布式系统的特点

要求一致 一定有分区容错 并发性(可处理多个并发请求)分散性(部署不同主机) 无全局时钟 (节点响应时间不同)网络分区(网络中断可能导致服务失联 比如 redis集群的脑裂现象)

所以要保证分布式系统的 一致性 有相当大的难度! 

CAP(一致性 可用性 分区容错性)理论也逐渐浮现 由此可以看出 一致性和可用性两者必须做一定程度的取舍 不仅要提高整个系统的性能(吞吐量 qps tps 响应延迟) 同时也需要保证子系统崩了其他还能用(分区隔离性)还有 子系统面对异常怎么处理(可用性)

为什么会有分布式事务 分布式事务定义?

举一个很经典的银行转账业务

你在A B 两个银行都存钱 现在需要把A 的转到 B 单机完全可以用@transaction 保证两个数据库操作原子性 

但是如果是这样的场景 A银行在北京的数据库 B银行在上海的数据库 他们没有共享事务管理

这个时候可能出现 A银行扣款成功 B银行收款失败 (网络超时 服务宕机等等) 数据丢了 

就出现了 跨服务操作导致数据不一致问题

同样 还有电商下单场景 

比如 电商平台 用户用来下单 订单服务 后端创建订单 支付服务 支付扣款 都是独立部署的微服务 全链路 先下单 创建订单 扣库存 支付扣款 三步 如果第三步失败(用户余额不足或者取消订单 前两步已经执行) 订单已经生成 不取消会变成僵尸订单 库存也扣了 不回复导致少货 但是没有支付 没花钱买了东西 那就很离谱了 现在我想保证三步操作 要么一次性成功 要么全部回滚 

问题:怎么在分布式环境下保证多个服务之间操作具有原子性?

事务一定是可以这么做的 那分布式系统有没有事务管理? 当然!

分布式事务指的是跨数据库或者多个服务实例的事务 就是为了保证隔离性和持久性的前提下 保证多节点之间操作的最终一致性! (当然 也可以实现强一致性 使用tcc)

区别一下数据库的ACID 他实现的是BASE的E(事件一致性)

对比单机事务来看 分布式事务在其基础上增加了更多的协议(2pc。tcc、Saga)来保证多节点操作一致性 同时还需要强依赖网络(如果延迟高 可能会丢包) 在故障恢复也需要人工设置人工处理池或者自动对账等等补偿 可能在性能上 单机事务不会非常重 而分布式事务在多数据库 多服务以及跨网络的情况下往往会给各个系统需要相互协调 因为这种协调而导致资源开销比较大(网络通信)性能相对而言比较低

问题2:怎么实现这种分布式系统?2pc 示例

出于学习目的 以下内容引自seata官方社区与pdai:

给出链接:快速启动 | Apache Seata

pdai:分布式系统 - 理论基础,理论及一致性算法 | Java 全栈知识体系

用户购买商品的逻辑 有三个微服务组成

库存服务 订单服务 账户(支付服务) 具体代码在链接内 这里不贴 不水篇幅

这里采用了全局事务的注解 @GlobalTransactional  简单实现了2pc

放在业务方法上

问题3:分布式事务实现的方式有哪些? 有什么区别吗? 适用于什么场景?

以下内容引自pdai:

这种问题 本质上其实是对分布式的理解不同 

我自己也看过不少分布式文章 pdai展现的体系在我看来可以说是比较全面的思考 

从理论上来看 也就是分布式系统必须保证的CAP 因为P(分区容错一定要保证) 同时对于不同业务场景下 要求强一致性和高可用性是不能同时兼容的 所以只能在AP/CP里二选一

这里我就不绕口 我就把他分为两类

要求强一致的分布式 CP + ACID(数据库层面) / 要求高可用 保证最终一致性的分布式系统 AP + BASE(e)(适用于业务层面)

简单说明:

强一致性的分布式事务模型 遵循 CP + ACID (强一致+分区容错)要求数据的强一致性 就是 XA协议  他是一个基于数据库层面的事务协议 由事务管理器(TM)和本地资源管理器(RM)事务管理器负责调度所有本地RM事务的执行或者回滚 MYSQL ORACLE都实现了XA 协议 衍生的协议是2pc和3pc

最终一致性的分布式事务模型 遵循AP + BASE (高可用+分区容错) 允许一定时间内不同节点的数据不一致 但是要求最终一致 基于业务层的实现方式有tcc(try confirm cancel)与 saga (长事务会发布一个消息/事件来触发saga里下一个本地事务的执行 如果某个事务执行失败则对之前所有成功的内容全部回滚 最常用的实现是基于事件与基于命令的方式)

保证最终一致性还可以通过消息表(把分布式事务拆分成本地事务)/ 消息队列(基于mq的分布式事务方案其实是对本地消息表的封装 把本地消息表基于mq内部 其他方面的协议基本和本地消息表一致)还有就是最大努力通知 (定期校验) 对mq的进一步优化 如果事务未能接收到新消息 就可以调用事务主动方提供的消息校验接口主动获取

具体细则我单出一个贴

分布式是如何部署在项目的 分布式在实际应用里 到底是本机还是云服务?

首推云服务 需要基于云原生技术 集容器云、DevOps、服务治理为一体 支持对不同云平台 IaaS、PaaS 服务的适配

以下是个人见解

具体适用场景:

  • 场景 1:大规模部署,业务并发量高(如月底支付高峰期 TPS>1000),需通过云服务 “弹性扩展” 能力动态新增节点(可伸缩性设计 核心服务支持水平扩展);
  • 场景 2:多区划部署(如覆盖全省 10 + 地市),通过云服务 PaaS 能力(如容器云、云数据库)实现 “区域隔离 + 资源按需分配”(拆分策略 按区划水平分库 要求);
  • 场景 3:DevOps 自动化交付,通过云服务 DevOps 平台实现 “微服务持续集成 / 持续部署(CI/CD)”,减少人工运维成本(技术平台 快速交付、运维自动化 需求);
  • 云服务类型适配:文档支持 混合云 部署 —— IaaS 层(虚拟机、存储)可使用云资源,PaaS 层(中间件、容器平台)可使用自研或第三方云服务(如阿里云 Redis、华为云 Seata)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值