【项目亮点】大厂中分布式事务的最佳实践 问题产生->难点与权衡(偏爱Saga)->解决方案

【项目亮点】大厂中分布式事务的最佳实践 问题产生->难点与权衡->解决方案->底层实现->应用案例

不断有同学问我大厂中实践分布式事务的问题,这里从分布式事务的产生,到强弱一致性与性能的权衡,再到最终落地的解决方案,再到实际的代码实现,再到我工作中实际使用SAGA模式的应用案例,一篇文章讲清楚.

问题的产生

83.7%分布式事务的产生都是因为拆分微服务导致的:

过去:
曾经在单体服务的时代,所有的数据库操作都是单体服务和mysql集群直接交互
比如电商中的下单操作,先更新订单,再扣减库存
订单和库存都在同一个数据库中,可以使用本地事务保证ACID特性现状:
现在该服务拆分成了一大堆微服务,其中订单服务和库存服务成了两个服务
那么更新订单和扣减库存就成了两个RPC,数据也属于不同的数据库
这时候,如果更新订单成功了,扣减库存失败了(网络问题或者库存不足)
就会出现一致性问题目标
分布式事务的目标就是让保证订单和库存数据的一致性至于是(回滚/补偿 还是重试)(TCC(又分为本地和远端,一般说的SEATA那种都是远端实现)  SAGA型  最大努力通知型  可靠消息型)
我们一会儿再说

一句话概括,分布式事务就是RPC和MQ没法像本地事务那样保证ACID的特性,为了(尽可能,最多保证几个9不可能完全)保证数据库操作,RPC,MQ三者混合使用时的原子性与一致性,而引入的解决方案.

难点与权衡 && 为什么大厂更偏爱Saga分布式事务?

分布式事务的权衡本质上是对性能和一致性的权衡.
熟悉CAP理论的小伙伴都知道,P(分区容错性)是一定要保证的,而C(一致性)和A(高可用)就要做一个权衡了. 而在互联网的业务中,对性能的要求是很高的,不可能为了保证强一致性而导致系统性能出问题.
所以分布式事务中强一致性的方案实际应用的很少. 我们常常在保证高性能的同时,保证最终一致性.
我待过的团队都更倾向于使用SAGA模式来解决分布式事务问题.原因如下:

强一致性方案,对性能损耗严重 直接pass(比如2PC,3PC)
最大努力通知型,一致性太差,连最终一致性都无法保证 直接pass最终一致性方案 主流的有SAGATCC模式TCC模式,对代码侵入性太大了,需要把流程改造成try->confirm->cancel
的形式,try锁定的资源只有事务完成或者超时才会释放. 
而且部分框架TCC的实现需要依赖TM(事务管理)集群,TM集群也是潜在的性能瓶颈的风险.所以我们更倾向于使用Saga模式来实现分布式事务
Saga模式引入了全局事务和分支事务的概念,每个分支事务除了业务逻辑还有补偿逻辑
如果调用链路 A->B->C->D ,比如执行到C的时候抛了异常,则从C开始逆向执行补偿逻辑
补偿例子: A->B->C(执行抛出异常)->C补偿->B补偿->A补偿
重试例子: A->B->C(执行抛出异常)->D  执行完了,C会一直重试,直到C执行成功或者大于配置的阈值时停止当然除了补偿,还可以用配置重试保障一致性
一般来说,我们像更新单据这种操作更倾向于重试
而像扣减库存这种操作更倾向于补偿 (因为扣减库存失败绝大多数是因为库存不足,重试没有意义)

这里多提一嘴,很多分布式事务解决方案比如TCC或者SAGA都有两种实现方式 :1.引入TM事务协调器来管理协调事务 2.本地建表分布式方式来管理协调事务 个人建议接入的时候最好选择方式2分布式的方式,最好不要依赖TM(事务管理)集群,TM集群也是潜在的性能瓶颈的风险

解决方案

本地事务信息表+定时任务 实现
核心思想: 用本地事务表 驱动 MQ(本地事务能保证一致性与原子性)
在这里插入图片描述

我们知道,之所以会有不一致问题,说白了就是因为MQRPC
也就是说如果全部操作都是本地事务,那就能保证ACID,当然也包括一致性与原子性
那把MQ/RPC转成本地事务不就行了?
或者说: 用本地事务表 驱动 MQ/RPC
当然,这种思想好,但实际实现会有严重的性能问题(反射)那么,我们退而求其次,使用消息队列中间件来让各个分支事务通信(具体见上图),
当各个本地事务之间要通信感知彼此执行成功还是失败时,
这个通信的消息,可以用本地事务表来驱动,
来保证了消息和业务逻辑的一致性.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/721.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言__动态内存管理__复习篇6】

目录 前言 一、动态内存管理 二、动态内存函数 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 三、动态内存常见的6个使用错误 3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL 3.2 越界访问动态内存空间 3.3 对非动态开辟的内存使用free释放 3.4 使用free只释放了…

AI时代,我要如何学习,才能跟上步伐

在21世纪这个被数据驱动的时代,人工智能(AI)已经渗透到我们生活的方方面面。无论是智能手机中的语音助手、在线客服的聊天机器人,还是自动驾驶汽车,AI的应用都在告诉我们一个信息:未来已来。因此&#xff0…

1.微服务介绍

完整的微服务架构图 注册中心 配置中心 服务集群 服务网关 分布式缓存 分布式搜索 数据库集群 消息队列 分布式日志服务 系统监控链路追踪 Jenkins docker k8s 技术栈 微服务治理: 注册发现、远程调用、负载均衡、配置管理、网关路由、系统保护、流量…

企业单位IPTV数字电视直播与点播系统-中国卫通怀来地球站IPTV数字电视直播与点播系统应用浅析

企业单位IPTV数字电视直播与点播系统-中国卫通怀来地球站IPTV数字电视直播与点播系统应用浅析 由北京海特伟业科技有限公司任洪卓发布于2024年4月19日 一、运营商光猫接入企业/单位IPTV数字电视直播与点播系统建设概述 中国卫通怀来地球站,位于怀来县土木镇&#xf…

小球反弹(蓝桥杯)

文章目录 小球反弹【问题描述】答案:1100325199.77解题思路模拟 小球反弹 【问题描述】 有一长方形,长为 343720 单位长度,宽为 233333 单位长度。在其内部左上角顶点有一小球(无视其体积),其初速度如图所…

CentOS 7静默安装Oracle 11g(记一次最小化CentOS 7安装Oracle 11g的经历)

# [pdf在线免费转word文档](https://orcc.online/pdf) https://orcc.online/pdf 1.最小化安装CentOS 7后首先设置一下固定IP 可以先查询一下自己的网卡设备的名称,是ens33,所以网卡配置文件名称就是ifcfg-ens33(前面的ifcfg-不用管&#xf…

HCIP-Datacom-ARST必选题库_01_ACL【7道题】

一、单选 1.下面是一台路由器的部分配置,关于该配置描述正确的是: 源地址为1.1.1.1的数据包匹配第一条ACL语句rule 0,匹配规则为允许 源地址为1.1.1.3的数据包匹配第三条ACL语句rule 2,匹配规则为拒绝 源地址为1.1.1.4的数据包匹配第四条ACL语句rule 3,匹配规则为允…

【Python】函数(纯干货版)

目录 什么是函数 函数定义 函数的文档说明 局部变量和全局变量 综合案例:模拟实现ATM界面 什么是函数 函数是组织好的,可重复使用的,用于实现特定功能的代码段,将功能封装在函数内,可供随时随地重复利用&#xff…

加固平板电脑加速国产化!应用场景大科普

随着时代的发展,国产化平板电脑已经开始慢慢的实现了,国产芯片、国产操作系统、国产 GPU、国产 GNSS 等众多关键技术的集成与应用。全新的平台,全新的突破,全新的应用,让国产加固型移动计算机系列往前进了一步。那么加…

如何用 AI 工具做数据分析与可视化?

(注:本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费) 万字长文,助力你用 AI 提升科研效率。 2024 年 4 月 14 日,应武汉大学信息管理学院的邀请,我和北京大学步一老师给几…

python 头文件怎么写

本文主要以python2为例。首先介绍一下Python头文件的编程风格,然后再给大家详细介绍import部分的基本用法。这两个部分就是Python中头文件的组成模块。 编程风格 #!/usr/bin/env python #在文件头部 ( 第一行 ) 加上 设置 Python 解释器 # -*- coding: utf…

【开源】使用Python+Flask+Mysql快速开发一个用户增删改查系统

项目演示 项目本身很简单,增删改查是几乎所有系统的骨架。正所谓万丈高楼平地起,学会了增删改查,航母就指日可待了:),光速入门,直接看演示图: 项目地址 https://github.com/mudf…

设计模式代码实战-责任链模式

1、问题描述 小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式&#xff…

大华相机C#学习之IDevice类

获取方式 Enumerator.GetDeviceByGigeIP() 通过IP地址获取设备对象。 private void test_Click(object sender, EventArgs e) {devicesEnumerator.EnumerateDevices();device Enumerator.GetDeviceByGigeIP("192.168.0.11"); } 常用属性 DeviceInfo 获取设备的信…

uniapp_微信小程序_预约时间组件的使用

一、官方文档 DatetimePicker 选择器 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com) 二、完成的效果 之前使用的是Calendar 日历 这个太耗性能了&#xff0c;直接页面卡顿&#xff0c;所以就换成以上选择器了 三、代码 <u-datetime-p…

短信登录session-redis

1.流程 1.1 发送验证码 模拟路径 http://127.0.0.1:8080/api/user/code?phone1335566 Request Method:POSTcontroller层 /*** 发送手机验证码*/PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {…

C#自定义窗体更换皮肤的方法:创建特殊窗体

目录 1.窗体更换皮肤 2.实例 &#xff08;1&#xff09;图片资源管理器Resources.Designer.cs设计 &#xff08;2&#xff09;Form1.Designer.cs设计 &#xff08;3&#xff09;Form1.cs设计 &#xff08;4&#xff09; 生成效果 &#xff08;5&#xff09;一个遗憾 1.窗…

【银角大王——Django课程Day1】

Django框架第一课 安装Django框架方式一&#xff08;命令行的形式创建Django项目&#xff09;方式二&#xff08;适合企业版的pycharm&#xff09;默认文件介绍app文件介绍快速上手我的导包一直爆红是因为我没使用解释器&#xff0c;没导入包&#xff0c;去设置里面导入包即可—…

在 Node.js 中配置代理 IP 采集文章

不说废话&#xff0c;直接上代码&#xff1a; const http require(http); const https require(https);// 之后可以使用 http 或 https 模块发起请求&#xff0c;它们将自动使用配置的代理 // 代理ip&#xff1a;https://www.kuaidaili.com/?refrg3jlsko0ymg const proxy …

OpenHarmony实战开发-如何视频弹幕功能。

介绍 本示例介绍如何使用ohos.danmakuflamemaster和ohos.gsyvideoplayer开发支持视频弹幕的播放器。可以自定义弹幕样式、占据屏幕宽度&#xff0c;发送弹幕&#xff0c;开关弹幕视图。 效果图预览 使用说明 点击播放按钮&#xff0c;进行视频播放&#xff0c;弹幕自动开启点…