首页 > 其他分享 >阿里面试:秒杀的分布式事务, 是如何设计的?

阿里面试:秒杀的分布式事务, 是如何设计的?

时间:2024-10-26 09:11:09浏览次数:3  
标签:事务 Seata 面试 秒杀 一致性 尼恩 分布式

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 :

免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备
免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,完成职业升级, 薪酬猛涨!加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷1)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷2)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领
免费赠送 经典图书:《Java高并发核心编程(卷3)加强版》 面试必备 + 大厂必备 +涨薪必备 加尼恩免费领

免费赠送 资源宝库: Java 必备 百度网盘资源大合集 价值>10000元 加尼恩领取


阿里面试:秒杀的分布式事务, 是如何设计的?

尼恩特别说明: 尼恩的文章,都会在 《技术自由圈》 公号 发布, 并且维护最新版本。 如果发现图片 不可见, 请去 《技术自由圈》 公号 查找

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很多 分布式事务 的 重要的面试题:

秒杀的分布式事务, 是如何设计的?
抢购场景, 如何实现 分布式事务?
分布式事务了解吗?你们是如何解决分布式事务问题的?

Seata 如何实现 RC ?保证事务的隔离性?

Seata是如何解决分布式事务问题的? Seata 的使用场景有哪些?

Seata 如何实现 事务的隔离性?

如何实现 强弱一致性 结合的分布式事务?

现在Java面试分布式事务几乎是标配。而分布式系统、分布式事务本身比较复杂,大家学起来也非常头疼。

其中,一道问过无数次的面试题就是:

 面试题:分布式事务了解吗?你们是如何解决分布式事务问题的?  (标准答案:见末尾) 

友情提示:看完此文,在分布式事务这块,基本可以做到吊打面试官了。

最近有小伙伴在面试阿里,又遇到了相关的面试题。小伙伴懵了,因为没有遇到过,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V170版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取

1:一图解读分布式事务

首先奉上一张全网最为牛逼的图,给大家做个总览:

image.png

上面这个图比较复杂,后面会结合 《尼恩Java面试宝典》配套视频,进行视频的录制。
具体的内容,请参见 尼恩 的最新 文章:
'分布式事务' 圣经:从入门到精通,架构师尼恩最新、最全详解 (50+图文4万字全面总结 )

1:Seata 和Rocketmq 事务消息实现,实现 强弱结合型事务

秒杀/抢购 等场景,都是属于 强弱结合型 的数据一致性场景。
image.png

首先看看 RocketMQ 的事务消息, 能够保证本地操作 + 消息发送的原子性。

具体来说, 主要是保证了本地方法执行和消息发送在一个分布式事务中,要不全部成功,要不全部失败。

见下图:

image.png

RocketMQ 通过发送 half 消息来实现,下面详细说明一下:

  1. 消息发送方 向 Broker 发送一条 half 消息;
  2. half 消息发送成功后,消息发送方 执行本地事务;
  3. 如果 消息发送方 执行本地事务成功,则向 Broker 发送 commit 请求,否则发送 rollback 请求;
  4. 如果 Broker 收到的是 rollback 请求,则删除保存的 half 消息;
  5. 如果 Broker 收到的是 commit 请求,则把 half 消息投递到 真实 队列, 等待消费服务来拉取,然后删除保存的 half 消息;
  6. 如果 Broker 没有收到 rollback/commit 请求,则会发送请求到 Producer 查询本地事务状态,然后根据 Producer 返回的本地状态做 commit/rollback 相关处理。

Seata + Rocketmq 事务消息 结合

Seata + Rocketmq 事务消息 结合的目标:

  • 一 是保证 分布式事务 + 消息 发送的原子性。
  • 二 是 再通过mq的重试机制,去保证订阅者的最终一致性,

image.png

Seata 的改进主要在 prepare 阶段。

Seata 提供了一个 SeataMQProducer 类,把 RocketMQ 中 TransactionListener 的方法加入到全局事务。

见下面代码:

SeataMQProducer(final String namespace, final String producerGroup, RPCHook rpcHook) {
 super(namespace, producerGroup, rpcHook);
 this.transactionListener = new TransactionListener() {
  @Override
  public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
   return LocalTransactionState.UNKNOW;
  }

  @Override
  public LocalTransactionState checkLocalTransaction(MessageExt msg) {
   String xid = msg.getProperty(PROPERTY_SEATA_XID);
   if (StringUtils.isBlank(xid)) {
    LOGGER.error("msg has no xid, msgTransactionId: {}, msg will be rollback", msg.getTransactionId());
    return LocalTransactionState.ROLLBACK_MESSAGE;
   }
   GlobalStatus globalStatus = DefaultResourceManager.get().getGlobalStatus(SeataMQProducerFactory.ROCKET_BRANCH_TYPE, xid);
   if (COMMIT_STATUSES.contains(globalStatus)) {
    return LocalTransactionState.COMMIT_MESSAGE;
   } else if (ROLLBACK_STATUSES.contains(globalStatus) || GlobalStatus.isOnePhaseTimeout(globalStatus)) {
    return LocalTransactionState.ROLLBACK_MESSAGE;
   } else if (GlobalStatus.Finished.equals(globalStatus)) {
    LOGGER.error("global transaction finished, msg will be rollback, xid: {}", xid);
    return LocalTransactionState.ROLLBACK_MESSAGE;
   }
   return LocalTransactionState.UNKNOW;
  }
 };

在 prepare 阶段,SeataMQProducer 向 RocketMQ Broker 发送 half 消息,执行本地事务,如果执行成功,则强行把 LocalTransactionState 改回 UNKNOW,等待 TC 发送指令,决定是 commit 或 rollback。

如果执行失败,返回 ROLLBACK_MESSAGE,TC 下发指令,回滚全局事务。

Seata + Rocketmq 事务消息 结合的使用场景

如果 MQ Broker 没有收到 commit/rollback 消息,则会回查 Producer 本地事务状态,也就是上面代码中的 checkLocalTransaction。

checkLocalTransaction 检查 全局事务状态,使用 XID 去查询 全局事务,去决定 half 消息 是 抛弃还是 投递 。

集成 RocketMQ 之后,Seata 的分布式事务调用流程, 下面以 订单服务、库存服务两个服务为例:

image.png

Apache Seata 引入 RocketMQ 后,支持的分布式事务场景更加丰富,使得 Seata 可以用于 强一致性 + 弱一致性 结合的场景。

image.png

10. 面试题标准答案: 如何解决分布式事务问题的?

现在Java面试,分布式系统、分布式事务几乎是标配。而分布式系统、分布式事务本身比较复杂,大家学起来也非常头疼。

 面试题:分布式事务了解吗?你们是如何解决分布式事务问题的? 

Seata AT/TCC 和 MQ异步确保型 事务 是在生产中最常用。

  • 强一致性模型, Seata AT/TCC 强一致方案 模式用于强一致主要用于核心模块,例如交易/订单等。

  • 弱一致性模型。 MQ异步确保型 事务 弱一致方案一般用于边缘模块例如库存,通过MQ 原子消息和发布订阅,保证最终一致性,也可以业务解耦。

面试中如果你真的被问到,可以分场景回答:

(1)强一致性场景

对于那些特别严格的场景,用的是Seata AT模式来保证强一致性;

准备好例子:你找一个严格要求数据绝对不能错的场景(如电商交易交易中的库存和订单、优惠券),可以回答使用成熟的如中间件Seata AT模式。

 阿里开源了分布式事务框架seata经历过阿里生产环境大量考验的框架。  seata支持Dubbo,Spring Cloud。 

image.png

是Seata AT/TCC模式,保障强一致性,支持跨多个库修改数据;

  • 订单库:增加订单

  • 商品库:扣减库存

  • 优惠券库:预扣优惠券

(2)弱一致性场景

基于可靠消息的最终一致性,各个子事务可以较长时间内异步,但数据绝对不能丢的场景。可以使用异步确保型事务事。

可以使用基于MQ的异步确保型事务,比如电商平台的通知支付结果:

  • 积分服务:增加积分

  • 会计服务:生成会计记录

image.png

(3)强弱结合一致性场景

两阶段 提交,如 Seata AT/TCC模式,保障强一致性,支持跨多个库修改数据;

  • 订单库:增加订单
  • 商品库:扣减库存
  • 优惠券库:预扣优惠券

异步确保型事务,保障弱一致性,支持跨多个服务和系统修改数据,在下面的场景中相关的弱一致性操作为:

  • 积分服务:增加积分
  • 通知服务:发生通知

弱一致性部分:如果不是严格对数据一致性要求、或者由不同系统执行子事务的场景,如电商发送成功支付成功消息,只需要保障弱一致性即可。

image.png

Seata 新功能: 和Rocketmq 事务消息实现,实现 强弱结合型事务 , 具体参见下面的文章:

最新 Seata 集成了RocketMQ事务消息,Seata 越来越 牛X 了! yyds !

各大模式的总体对比:

属性 2PC TCC Saga 异步确保型事务 尽最大努力通知
事务一致性
复杂性
业务侵入性
使用局限性
性能
维护成本

说在最后:有问题找老架构取经

以上关于分布式事务的方案和场景,如果大家能对答如流,如数家珍,基本上 面试官会被你 震惊到、吸引到。

最终,让面试官爱到 “不能自已、口水直流”。offer, 也就来了。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会,可以找尼恩来改简历、做帮扶。

遇到职业难题,找老架构取经, 可以省去太多的折腾,省去太多的弯路。

尼恩指导了大量的小伙伴上岸,前段时间,刚指导中厂大龄34岁,被裁8月收一大厂offer, 年薪65W,转架构后逆天改命!

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

技术自由的实现路径:

实现你的 架构自由:

吃透8图1模板,人人可以做架构

10Wqps评论中台,如何架构?B站是这么做的!!!

阿里二面:千万级、亿级数据,如何性能优化? 教科书级 答案来了

峰值21WQps、亿级DAU,小游戏《羊了个羊》是怎么架构的?

100亿级订单怎么调度,来一个大厂的极品方案

2个大厂 100亿级 超大流量 红包 架构方案

… 更多架构文章,正在添加中

实现你的 响应式 自由:

响应式圣经:10W字,实现Spring响应式编程自由

这是老版本 《Flux、Mono、Reactor 实战(史上最全)

实现你的 spring cloud 自由:

Spring cloud Alibaba 学习圣经》 PDF

分库分表 Sharding-JDBC 底层原理、核心实战(史上最全)

一文搞定:SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系(史上最全)

实现你的 linux 自由:

Linux命令大全:2W多字,一次实现Linux自由

实现你的 网络 自由:

TCP协议详解 (史上最全)

网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!

实现你的 分布式锁 自由:

Redis分布式锁(图解 - 秒懂 - 史上最全)

Zookeeper 分布式锁 - 图解 - 秒懂

实现你的 王者组件 自由:

队列之王: Disruptor 原理、架构、源码 一文穿透

缓存之王:Caffeine 源码、架构、原理(史上最全,10W字 超级长文)

缓存之王:Caffeine 的使用(史上最全)

Java Agent 探针、字节码增强 ByteBuddy(史上最全)

实现你的 面试题 自由:

4800页《尼恩Java面试宝典 》 40个专题

免费获取11个技术圣经PDF:

标签:事务,Seata,面试,秒杀,一致性,尼恩,分布式
From: https://www.cnblogs.com/crazymakercircle/p/18503614

相关文章

  • 类型转换:面试题
    1.请问该代码是否有误?答:有误,之前说过byte在运算时会提升为int,所以是inta+b,c不能用byte.2.该如何修正代码?.答:我们可以将c的类型换成int.3.下列修正代码错在哪里?该如何正确修正?答:这么转换毫无意义,因为a和b本来就是byte类型,而且这样转换,a和b还是会提升为int。正确转换应......
  • Redis面试题扩展
    一、redis特性1、内存数据快,快,很快...2、工作单线程worker,串行化、原子操作,(IO线程是多线程)-避免上下文切换3、IO模型(epoll),天生支撑高并发4、kv模型,v具有类型结构5、具有本地方法,计算向数据移动。(a,b)=>交集6、二进制安全,Value最大512M二、Redis是单线程还是多线......
  • 面试真题:OOM(OutOfMemoryError)SOF(StackOverflow)你遇到过哪些情况
    前言本来想着给自己放松一下,刷刷博客,慕然回首,OOM?SOF?似乎有点模糊了,那就大概看一下Java面试题吧。好记性不如烂键盘***12万字的java面试题整理***OOM你遇到过哪些情况,SOF你遇到过哪些情况OOM:1,OutOfMemoryError异常除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生......
  • 2024最新互联网工程师 Java 面试八股文及答案整理
    2024金九银十即将结束,竟很多同学会问Java面试八股文有必要背吗?!!我的回答是:很有必要!!!!你可以讨厌这种模式,但你一定要去背,因为不背你就进不了大厂。国内的互联网面试,恐怕是现存的、最接近科举考试的制度。而且,我国的八股文确实是独树一帜。以美国为例,北美工程师面试比较重视算......
  • 深入解析 Aerospike高性能分布式数据库的利器
    1.Aerospike简介在当今大数据和高并发的时代,传统关系型数据库往往难以满足实时性和扩展性的需求。Aerospike作为一款高性能、低延迟的分布式NoSQL数据库,以其独特的架构和强大的功能,受到了业界的广泛关注。本文将深入探讨Aerospike的核心原理、关键特性、应用场景,以......
  • 面试华为遇到了经典动态规划题 - 怎么用go、C++进行编程解决
    华为的知名很大程度上源自于在经历过被美国的制裁和打压后不仅撑住了,而且还做出了相对于自己来说技术进步程度很大的芯片​。这是一个不小的成绩​。从个人的角度上来说,华为是最难进的一家大公司之一,它的面试标准很严格​。这不仅是筛选人才,在某种程度上来说也是由于求职市场......
  • etcd之etcd分布式锁及事务(四)
    1、etcd分布式锁及事务1.1前言分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这......
  • 【leetcode-面试经典 150 题】-4.删除有序数组中的重复项 II
    题目:给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用O(1)额外空间的条件下完成。示例1:输入:nums=[1,1,1,2,2,3]输出:5,nums=......
  • 【leetcode-面试经典 150 题】-1.合并两个有序数组
    题目:给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 ......
  • 12万字的java面试题及答案整理(2024新版)
    前言本来想着给自己放松一下,刷刷博客,慕然回首,final有哪些用法?static都有哪些用法?java的精度算法?java运算逻辑?异常处理?似乎有点模糊了,那就大概看一下Java基础面试题吧。好记性不如烂键盘***12万字的java面试题整理***final有哪些用法?final也是很多面试喜欢问的地方,但我觉得这个......