DTM在新交易平台的落地 | 业务平台

news2024/11/19 3:49:46

一、项目背景

在项目的发展过程中,我们将整个新交易平台(业务平台部专门为360集团内部打造的类似有赞、微盟的交易系统)微服务化,产生了店铺服务、商品服务、订单服务、优惠券服务、红包服务、用户服务、支付服务、履约服务、售后服务等等。并且这些服务由不同的语言开发。

当前端的用户提交订单,服务端需要完成以下操作:

  • 创建订单:需要在订单表中创建订单,唯一键为订单ID

  • 扣减库存:需要给用户下单的商品扣减库存

  • 核销优惠券:用户在下单前,选择了可使用的优惠券,提交订单时,则扣减这部分优惠券

  • 扣减红包:用户在下单前,选择了可使用的红包,提交订单时,则扣减这部分红包金额

  • 扣减积分:用户在下单前,如果有积分余额,提交订单时,则扣减这部分积分

  • 创建支付单:提交订单后,需要创建支付单,最终供用户支付

对于上述这个场景,如果在单体订单系统中,很容易使用数据库的事务来解决。但是一旦微服务化了之后,由于这些操作分布在不同的服务中间,则需要按顺序依次去调用各个过程。在这个过程中就会遇到许多进程故障、某一操作无法完成需回滚、重复请求等问题。因此我们就要考虑分布式场景下的事务一致性解决方案。

二、分布式方案选型

由于订单创建的过程中是需要回滚的,所以首先排除了消息通知类(消息通知、本地事务消息等)的模式。排除之后发现仅剩XA、TCC、SAGA,下面我们分析一下这三种事务模式

XA

XA协议最初由Tuxedo首先提出,后被提交给X/Open组织作为资源管理器(数据库)与事务管理器的接口标准。XA规范主要定义了全局事务管理器(TM)和局部资源管理器(RM)之间的接口。在XA中,本地的数据库扮演的是RM角色。目前,主流的数据库基本都支持XA事务,包括MySQL、Oracle、SQL Server和PostgreSQL。

XA一共分为两阶段:

  • 第一阶段(prepare):事务管理器(TM)会向所有参与者发送prepare消息,询问它们是否可以提交事务

  • 第二阶段 (commit/rollback):如果所有参与者都能够提交,则事务管理器(TM)向它们发送commit消息,让它们提交事务。如果有任何一个参与者不能提交,则协调器向它们发送rollback消息,让它们回滚事务。

849b5d109ca1535e860242bae1eafa03.png

通过这两个阶段操作,使所有的参与者数据都能保持一致性,但XA事务模式虽然能够保证分布式事务的一致性,但是由于是数据库层面的资源锁定,会带来一些性能上的开销。排除此模式

TCC

TCC是Try、Confirm、Cancel三个词语的缩写,最早是由 Pat Helland 于 2007 年发表的一篇名为《Life beyond Distributed Transactions:an Apostate’s Opinion》的论文提出。

TCC分为3个阶段

  • Try 阶段:尝试执行,完成所有业务检查(一致性), 预留必须业务资源(准隔离性)

  • Confirm 阶段:如果所有分支的Try都成功了,则走到Confirm阶段。Confirm真正执行业务,不作任何业务检查,只使用 Try 阶段预留的业务资源

  • Cancel 阶段:如果所有分支的Try有一个失败了,则走到Cancel阶段。Cancel释放 Try 阶段预留的业务资源。

TCC特点如下:

  • 并发度较高,无长期资源锁定

  • 开发量较大,需要提供Try/Confirm/Cancel接口

  • 一致性较好,不会有暴漏给用户待支付订单,最后又被取消的情况

  • TCC适用于订单类业务,对中间状态有约束的业务

但是由于我们系统存在历史逻辑,短时间内无法完全重构以支持资源预留,所以也排除了此模式

SAGA

SAGA最初出现在1987年Hector Garcaa-Molrna & Kenneth Salem发表的论文SAGAS里。其核心思想是将长事务拆分为多个短事务,由Saga事务协调器协调,如果每个短事务都成功提交完成,那么全局事务就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作。

Saga分为2个阶段

  • Action阶段:正向执行,无需做资源预留

  • Compensate阶段:如果某一个过程出错,调用补偿接口,依次进行资源逆向补偿

Saga事务的特点:

  • 并发度高,不用像XA事务那样长期锁定资源

  • 需要定义正常操作以及补偿操作,开发量比XA大,但比TCC小

  • 一致性较弱,对于订单创建,有可能出现待支付订单,最后又被取消的情况

由于Saga仅需要在发生异常需回滚时提供一个逆向补偿的接口,开发量较少,且几乎不用对历史业务逻辑进行改动。故采用此方案而接受短暂数据不一致的问题。

三、SAGA模式&DTM在创建订单过程中的实践

1、DTM分布式事务管理器的确认

确定了Saga模式,接着我们就要进行实施落地,如果自研分布式事务管理器有很大的开发工作,于是去寻找有没有符合我们实际需求的开源工具,最终确定两款比较成熟的开源系统,JAVA SEATA&&Golang DTM,由于seata仅支持Dubbo、Spring Cloud等协议,并且除java版本SDK外,其他语言的SDK完善度不高。DTM支持http、grpc协议。最终确定使用DTM。

接入DTM后的下单时序如下所示:

aadd75d96e0bc2fe519541132cca4373.png

首先看看,下单 api 的主要处理过程:

8e8dbe299039a953ad85f1185e384054.png

上面的代码首先创建了一个SAGA事务,然后添加了多个子事务,每个事务分支包括action和compensate两个操作,分别为Add函数的第一第二个参数。子事务定好之后提交给dtm。dtm收到saga提交的全局事务后,会调用所有子事务的正向操作,如果所有正向操作成功完成,那么事务成功结束。如果有正向操作失败,例如账户库存不足,那么dtm会调用各分支的补偿操作,进行回滚,最后事务成功回滚。

  • 进程crash问题 dtm的saga事务进行过程中,如果发生进程crash,那么dtm会进行重试,保证操作会最终完成

  • 回滚问题 上述这个saga事务中,如果扣减库存时发现库存不足,则返回failure,会进行回滚。dtm 会记录哪些操作已完成,并回滚相关的操作

但是由于分布式事务的引入,因为网络的时序无法保证,会引入幂等、空回滚、悬挂等新问题。

2、解决重复请求、空回滚、悬挂等问题

分布式事务之所以难,主要是因为分布式系统中的各个节点都可能发生各种非预期的情况。分布式系统最大的敌人可能就是NPC了,在这里它是Network Delay, Process Pause, Clock Drift的首字母缩写。我们先看看具体的NPC问题是什么:

  • Network Delay,网络延迟。虽然网络在多数情况下工作的还可以,虽然TCP保证传输顺序和不会丢失,但它无法消除网络延迟问题。

  • Process Pause,进程暂停。当基于某些需要,例如内存垃圾回收、CPU 排队、服务迁移等,某服务会暂时暂停。

  • Clock Drift,时钟漂移。分布式系统涉及大量的服务器,而不同服务器通常使用 NTP (Network Time Protocol)协议将本地设备的时间与时间服务器对齐对齐后,通常会导致本地时间跳跃。

分布式事务既然是分布式的系统,自然也有NPC问题。因为没有涉及时间戳,带来的困扰主要是NP。我们以扣减库存为例,看看NP带来的影响

3、网络异常状态下库存扣减问题

c9d506a034f32ae141428c0379c387f5.png

一般情况下,一个SAGA异步补偿时的执行顺序是,先执行完库存扣减,再执行库存回滚,但是由于N,则有可能库存扣减的网络延迟大,导致先执行库存回滚,再执行库存扣减。

这种情况就引入了分布式事务中的两个难题:

  • 空补偿:compensate执行时,action未执行,事务分支的compensate操作需要判断出action未执行,这时需要忽略compensate中的业务数据更新,直接返回

  • 悬挂:action执行时,compensate已执行完成,事务分支的action操作需要判断出compensate已执行,这时需要忽略action中的业务数据更新,直接返回

分布式事务还有一类需要处理的常见问题,就是重复请求

  • 幂等: 由于任何一个请求都可能出现网络异常,出现重复请求,所有的分布式事务分支操作,都需要保证幂等性

上图中,库存扣减操作超时而执行的库存回滚,若在商品服务执行成功,但反馈的结果由于 NPC 问题不能到达事务调度器,那么事务调度器还有可能再次发送库存回滚。这就意味着商品服务的库存回滚操作会被多次重复调用。我们必须保证分布式事务的全部操作分支保证幂等性。也就是重复调用操作分支,但不会产生叠加的影响。

不论空补偿、悬挂还是幂等,都需要在业务逻辑层面做出判定。通常的做法是通过分布式事务事件日志的方案来标识操作状态,进而决定是否需要处理空补偿和防止悬挂。

4、DTM解决方案在库存扣减服务中的实现

如果没有一个通用的操作方法去解决幂等、悬挂、空回滚等问题,系统也面临着大量的开发工作,并且每个业务都要仔细处理这三张问题。好在看到了DTM的子事务屏障技术。

子事务屏障技术的原理是,在本地数据库,建立分支操作状态表dtm_barrier,唯一键为全局事务id-分支id-分支操作

  • 开启本地事务

  • 对于当前操作op(action|compensate),insert ignore一条数据gid-branchid-op,如果插入不成功,提交事务返回成功(常见的幂等控制方法)

  • 如果当前操作是compensate,那么在insert ignore一条数据gid-branchid-action,如果插入成功(注意是成功),则提交事务返回成功

  • 调用屏障内的业务逻辑,如果业务返回成功,则提交事务返回成功;如果业务返回失败,则回滚事务返回失败

由于我们的库存服务使用的是java语言,DTM中java版本SDK还不支持SAGA事务的子事务屏障,于是我们使用此原理自己研发 

b13d154e396fc74c1f615c10e6b0694f.png

在此机制下,我们看一下怎么解决乱序相关的问题

  • 空补偿控制:如果action没有执行,直接执行了compensate,那么插入gid-branchid-action会成功,不走屏障内的逻辑,保证了空补偿控制

  • 幂等控制:gid-branchid-{action/compensate}在任何一个操作都无法重复插入唯一键,保证了不会重复执行

  • 防悬挂控制:action在compensate之后执行,由于执行compensate时会在插入gid-branchid-action,导致action请求插入gid-branchid-action不成功,就不执行屏障内的逻辑,保证了防悬挂控制

总结

伴随着业务的快速地发展、越来越高的业务复杂度,几乎每个公司的系统都会从单体走向分布式,特别是转向微服务架构。分布式事务本身就是一个技术难题,如果没有合适的框架、工具,分布式事务会大大的提高流程的复杂度,会带来很多额外的开销工作。经过我们调研和探索,很好地利用DTM事务管理器与系统结合。将分布式事务相关逻辑全部交由 DTM处理,而让我们相应的开发者更聚焦于业务本身,只需要安心写好相关操作和补偿操作即可。

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

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

相关文章

前端系列17集-和公司架构师在学习vue3-springboot

SyntaxError: "undefined" is not valid JSON at JSON.parse (<anonymous>) 这个错误通常意味着你正在尝试将一个非 JSON 格式的数据转换成 JSON 格式。为了修复这个问题&#xff0c;你需要找到导致错误的代码行并检查它的输入数据是否符合 JSON 格式标准。 这…

chatgpt赋能python:Python中构造函数的作用

Python中构造函数的作用 Python是一种高级编程语言&#xff0c;其强大的面向对象编程&#xff08;OOP&#xff09;功能是其流行的主要原因之一。在Python中&#xff0c;通过使用构造函数可以轻松创建对象实例&#xff0c;并为对象的属性赋值。在本文中&#xff0c;我们将介绍P…

剖析CPU性能火焰图生成的内部原理

关注开发内功修炼&#xff0c;掌握硬核技术原理 大家好&#xff0c;我是飞哥&#xff01; 在进行CPU性能优化的时候&#xff0c;我们经常先需要分析出来我们的应用程序中的CPU资源在哪些函数中使用的比较多&#xff0c;这样才能高效地优化。一个非常好的分析工具就是《性能之巅…

到底什么是“5G新通话”?

今天这篇文章&#xff0c;我们来聊聊今年很热门的一个概念——“5G新通话”。 小枣君当年第一次听说“5G新通话”的时候&#xff0c;还以为是VoNR的“新马甲”。 后来&#xff0c;仔细研究了一下&#xff0c;我才知道&#xff0c;原来“5G新通话”并不是VoNR&#xff0c;而是Vo…

chatgpt赋能python:Python中的构造函数

Python 中的构造函数 Python 是一门广泛应用于各种应用领域的高级编程语言&#xff0c;它支持不同的编程范式&#xff0c;包括面向对象编程。在面向对象编程中&#xff0c;构造函数是一个重要的概念。本文将介绍 Python 中的构造函数&#xff0c;并介绍如何使用它们来创建对象…

PFTL201C 10KN 3BSE007913R0010 专为测量该分力而设计

在许多带材加工中&#xff0c;带材张力会在轧辊上产生一个水平分力...或者&#xff0c;通过设计&#xff0c;它可以做到这一点。概述使用该水平分力测量带材张力非常有利。称重传感器的尺寸可仅测量带材张力&#xff0c;不包括辊的皮重。结果是优化了测量精度。另一个优势是ABB…

以支付宝为例,聊聊Web安全的三个攻防姿势

我们最常见的Web安全攻击有以下几种 XSS 跨站脚本攻击CSRF 跨站请求伪造clickjacking 点击劫持/UI-覆盖攻击 下面我们来逐个分析 一、XSS 跨站脚本攻击 跨站脚本攻击&#xff08;Cross Site Scripting&#xff09;&#xff0c;为了不和层叠样式表&#xff08;Cascading Styl…

直播倒计时 1 天 | SOFAChannel#33《Occlum x EDMM=更安全好用的机密计算 LibOS》

Occlum 是蚂蚁集团于 2019 年开源的机密计算操作系统&#xff0c;也是 Linux 基金会机密计算联盟官方项目&#xff0c;荣列 2021“科创中国”开源创新榜。2022 年 12 月 10 日&#xff0c;Occlum 正式发布 v1.0 版本。学术成果发表在 ASPLOS20。Occlum 可让复杂应用轻松获得机密…

冷气机、空调扇、饮水机、液晶驱动VK0256C LQFP52段码LCD液晶显示驱动芯片技术资料

品牌&#xff1a;永嘉微电/VINKA 型号&#xff1a;VK0256C 封装形式&#xff1a;LQFP52 年份&#xff1a;新年份 KPP2649 概述: VK0256C是一个点阵式存储映射的LCD驱动器&#xff0c;可支持最大256点&#xff08;32EGx8COM&#xff09;的LCD屏。单片机可通过3/4线串行接口配…

界面控件DevExpress WinForms全新的UI模板,解决各种业务线需求!

去年秋天DevExpress官方发布了一个新的 WinForms UI模板预览版&#xff08;第一个EAP只提供给DevExpress宇宙版激活的用户&#xff09; &#xff0c;这些精炼的、随时可用的“模板”旨在启动表单设计/开发过程。有了这个模板&#xff0c;用户可以创建/交付现成的UI解决方案&…

ISO21434 分布式网络安全(四)

目录 一、概述 二、目标 三、输入 四、要求和建议 4.1 供应商能力 4.2 报价申请 4.3 责任的协调 五、输出 一、概述 如果分发了一个项目或组件的网络安全活动的责任&#xff0c;则适用本条款。 本条款描述了对分布式网络安全活动的管理&#xff0c;并适用于&#xff1a…

win10没有hyper-v功能解决方法

1.在Win10搜索框,搜索PowerShell 2.打开 Windows PowerShell&#xff0c;输入 systeminfo 命令 如果四个全为 “是”&#xff0c;则表示支持 Hyper-V 功能 3.桌面新建一个记事本文件&#xff0c;将它的后缀改成bat&#xff0c;复制下面的代码 pushd "%~dp0"dir /b …

5、USB协议学习:USB的枚举过程

文章目录 枚举顺序枚举过程标准请求bmRequestTypebReqest请求类型 GetDescriptor设备描述符设备描述符定义获取设备描述符返回设备描述符 配置描述符配置描述符定义获取配置描述符返回配置描述符 接口描述符&端点描述符&HID描述符接口描述符定义返回接口描述符HID描述符…

基于 ESP32 的高级气象站,带有 BME280 和实时天气数据

在这个项目中,我们将学习如何创建一个气象站,它将在网络服务器中显示来自 BME280 模块的读数和来自 OpenWeatherMap API 的实时天气数据。该设备将从 BME280 传感器获取温度、湿度、气压和高度,并从 OpenWeatherMap API 获取外部温度、湿度、天气状况以及日出和日落。我们可…

基于springboot+vue的校园二手交易市场

一、项目背景介绍&#xff1a; 校园二手交易市场是大学生生活中的重要组成部分&#xff0c;它为学生提供了一个便捷的方式来买卖物品。然而&#xff0c;传统的校园二手交易方式存在着信息不对称、交易风险高等问题。为了解决这些问题&#xff0c;基于Spring Boot和Vue的校园二手…

从瀚海到万家,易开得为净水器开辟新航道

前不久&#xff0c;我们报道过一家净水器品牌易开得&#xff0c;将“航母展台”搬到了家电行业展的事情。不仅现场观众纷纷前去打卡&#xff0c;网络读者们也都倍感神奇直呼666。 大众的兴奋感从何而来呢&#xff1f;我想是因为航母这类“重器”和卫星、导弹、航天飞机一样&…

【JUC基础】12. 线程池(一)

1、前言 我们知道多线程的使用&#xff0c;是为了最大限度发挥现代多核处理器的计算能力&#xff0c;提高系统的吞吐量和性能。但是如果不加以控制和管理&#xff0c;随意使用多线程&#xff0c;对系统性能反而会有不利的影响。线程数量和系统CPU资源是息息相关的&#xff0c;…

FPGA纯vhdl实现XGMII接口10G万兆网UDP协议 配合10G Ethernet PCS/PMA使用 提供工程源码和技术支持

目录 1、前言2、我这里已有的UDP方案3、详细设计方案本 10G-UDP 协议栈功能和性能描述本 10G-UDP 协议栈设计框图用户发送AXIS接口描述用户接收AXIS接口描述控制接口描述XGMII接口描述 4、vivado工程详解10G-UDP协议栈10G Ethernet PCS/PMA IP核 5、上板调试验证并演示6、福利&…

自动缩放Kubernetes上的Kinesis Data Streams应用程序

想要学习如何在Kubernetes上自动缩放您的Kinesis Data Streams消费者应用程序&#xff0c;以便节省成本并提高资源效率吗&#xff1f;本文提供了一个逐步指南&#xff0c;教您如何实现这一目标。 通过利用Kubernetes对Kinesis消费者应用程序进行自动缩放&#xff0c;您可以从其…

nps与npc内网穿透搭建

1.简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发&#xff0c;可支持任何tcp、udp上层协议&#xff0c;支持内网http代理、内网socks5代理、p2p等&#xff0c;并带有功能强大的web管理端。 使用内网穿透技术可以使你在公共网络环境也能…