面试题-----微服务业务

目录

限流

为什么要限流?

限流的实现方式:

Tomcat:可以设置最大连接数(适合单体项目)

网关,令牌桶算法

自定义拦截器

你们项目中有没有做过限流?怎么做的?

令牌桶和漏桶算法有什么区别?

原理

流量处理特性

分布式事务

Seata架构

XA模式

AT模式(弥补了XA模型中资源锁定周期过长的缺陷)(高可用性)

TCC模式(高可用性,高耦合)

MQ分布式事务(高性能,实时性低)

你们采用哪种分布式事务解决方案?

分布式服务的接口幂等性如何设计?

token+redis

分布式锁

回答

你们项目中使用了什么分布式任务调度?

xxl-job路由策略有那些?


限流

为什么要限流?

1.并发的确大(突发流量)

2.防止用户恶意刷接口

限流的实现方式:

Tomcat:可以设置最大连接数(适合单体项目)

  • Nginx,漏桶算法

控制速率(突发流量)

控制并发连接数

网关,令牌桶算法

自定义拦截器

你们项目中有没有做过限流?怎么做的?

1,先来介绍业务,什么情况下去做限流,需要说明 QPS 具体多少

  • 我们当时有一个活动,到了假期就会抢购优惠券,QPS 最高可以达到 2000,平时 10 - 50 之间,为了应对突发流量,需要做限流
  • 常规限流,为了防止恶意攻击,保护系统正常运行,我们当时系统能够承受最大的 QPS 是多少(压测结果)
    2,nginx 限流
  • 控制速率(突发流量),使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量
  • 控制并发数,限制单个 ip 的链接数和并发链接的总数
    3,网关限流
  • 在 spring cloud gateway 中支持局部过滤器 RequestRateLimiter 来做限流,使用的是令牌桶算法
  • 可以根据 ip 或路径进行限流,可以设置每秒填充平均速率,和令牌桶总容量

令牌桶和漏桶算法有什么区别?

原理

  • 漏桶算法:可以看作是一个底部有漏洞的桶,无论请求以多快的速度进入桶内,漏桶都会以固定的速率将请求 "漏出" 进行处理。如果桶满了,后续进入的请求就会被丢弃。比如,一个漏桶每秒钟能处理 10 个请求 ,如果在某一秒钟内涌入了 30 个请求,那么除了这一秒正常处理的 10 个请求,另外 20 个请求会被丢弃。
  • 令牌桶算法:系统会以恒定的速率向桶中放入令牌,每个请求在处理之前需要先从桶中获取一个令牌,如果桶中有足够的令牌,请求就能被处理;如果没有令牌,请求就需要等待或者被丢弃 。例如,令牌桶以每秒 10 个的速率生成令牌,桶的容量是 100 个,如果在某一时刻桶中有 20 个令牌,此时来了 30 个请求,那么其中 20 个请求可以立即获取到令牌并被处理,剩下 10 个请求则需要等待新的令牌生成。

流量处理特性

  • 漏桶算法:能够强行限制数据的传输速率,使请求以均匀的速率被处理,所以它可以很好地平滑突发流量 ,但在面对突发流量时,无法利用系统的瞬间处理能力,可能会导致资源利用率不足。比如,在电商大促瞬间有大量抢购请求,漏桶只能按照固定速率处理,即使服务器还有处理能力,也无法及时处理更多请求。
  • 令牌桶算法:在保持平均速率限制的同时,允许一定程度的突发流量,只要桶内有足够的令牌,就可以快速处理请求,充分利用系统资源。例如,平时系统处理请求速率是每秒 10 个,在促销活动时,由于之前积累了一定数量的令牌,短时间内可以处理更多请求。

分布式事务

Seata架构

Seata 事务管理中有三个重要的角色:

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与 TC 交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

XA模式

一、全局事务开启(TM 主导)

TM(事务管理器)作为全局事务的发起方,首先执行 1.1 开启全局事务 操作,标记一个分布式事务的开始。这一步是整个 XA 模式的起点,明确事务的边界,后续所有分支事务都将关联到这个全局事务中,为跨微服务的业务操作提供统一的事务上下文。

二、分支事务初始化(TM 调用 + RM 执行)

  1. TM 调用分支 :TM 执行 1.2 调用分支 动作,触发微服务中的业务逻辑执行。此时,微服务内的 RM(资源管理器)开始介入分支事务处理,为后续注册和执行分支事务做准备。
  2. RM 注册分支事务 :微服务中的 RM 执行 1.3 注册分支事务,主动向 TC(事务协调者)登记当前分支事务。这一步让 TC 感知到分支事务的存在,建立全局事务与分支事务的关联,TC 后续可通过该关联管理分支事务的状态。
  3. RM 执行业务 SQL :RM 内部执行 1.4 执行业务 SQL ,在分支事务的上下文里处理具体业务逻辑(如数据库增删改操作 )。但与本地事务不同,XA 模式下这一步 仅执行 SQL 但不提交,为二阶段的统一提交 / 回滚预留控制入口,保证分布式事务的原子性。
  4. RM 报告事务状态 :RM 完成业务 SQL 执行后,执行 1.5 报告事务状态,将分支事务的执行结果(成功或失败)反馈给 TC。TC 由此收集各分支事务的状态,为二阶段的决策提供依据。

三、全局事务二阶段决策(TC 主导)

  1. TC 检查分支事务状态 :TC 执行 2.2 检查分支事务状态,汇总各 RM 报告的分支事务执行结果。这一步是 XA 模式的核心决策点,TC 需基于所有分支事务的状态,判断全局事务是提交还是回滚。
  2. TC 发起全局指令 :根据分支事务状态,TC 执行 2.1 提交、回滚全局事务 操作:
    • 所有分支事务均成功 ,TC 向各 RM 发送 2.3 提交 指令,要求完成分支事务的最终提交,保证全局事务的一致性;
    • 任意分支事务失败 ,TC 向各 RM 发送 2.3 回滚 指令,要求撤销已执行的分支业务操作,避免数据不一致。

四、分支事务最终执行(RM 响应 TC 指令)

RM 接收 TC 下发的 2.3 提交 / 回滚 指令后,执行分支事务的最终操作:

  • 若指令是提交,RM 会提交一阶段执行的 SQL,将业务操作持久化到数据库,完成分支事务;
  • 若指令是回滚,RM 会回滚一阶段执行的 SQL,撤销未提交的业务操作,保证数据恢复到事务执行前的状态。

AT模式(弥补了XA模型中资源锁定周期过长的缺陷)(高可用性)

一、全局事务开启(TM 主导触发)

TM(事务管理器)执行 1.1 开启全局事务,标记分布式事务的起始,为后续分支事务划定统一的事务边界,让 TC(事务协调者)和 RM(资源管理器)感知全局事务上下文。

二、分支事务初始化与执行(RM 主导阶段一)

  1. TM 调用分支 :TM 执行 1.2 调用分支,触发微服务内的业务逻辑执行,此时微服务中的 RM 开始处理分支事务,进入 AT 模式的核心阶段。
  2. RM 注册分支事务 :RM 执行 1.3 注册分支事务,主动向 TC 登记当前分支事务,建立全局事务与分支事务的关联,使 TC 能够管理分支事务的状态。
  3. RM 记录 undo-log(数据快照) :RM 在执行业务 SQL 前,会记录 更新前后的数据快照(undo-log),内容包含数据修改前的旧值、修改后的新值等。这是 AT 模式区别于 XA 模式的关键:通过快照实现 "柔性" 事务控制,避免长时间锁定资源。
  4. RM 执行业务 SQL 并提交 :RM 执行 1.4 执行业务 SQL 并提交 ,直接完成本地事务的提交(与 XA 模式 "一阶段不提交" 不同 )。此时业务数据已落库,但由于记录了 undo-log,后续可通过回滚快照实现最终一致性,一阶段即可释放数据库锁,解决了 XA 模式资源锁定周期过长的问题。
  5. RM 报告事务状态 :RM 执行 1.5 报告事务状态,将分支事务的执行结果(成功或失败)反馈给 TC,TC 由此收集各分支事务的状态,为二阶段决策提供依据。

三、全局事务二阶段决策(TC 主导)

  1. TC 检查分支事务状态 :TC 执行 2.2 检查分支事务状态 ,汇总各 RM 报告的分支事务执行结果,判断全局事务的最终走向:
    • 所有分支事务均成功 ,TC 向各 RM 发送 2.3 提交 指令;
    • 任意分支事务失败 ,TC 向各 RM 发送 2.3 回滚 指令。
  2. TC 发起全局指令 :TC 执行 2.1 提交、回滚全局事务 操作,根据分支事务状态,统一向 RM 下发提交或回滚的指令,驱动各分支事务完成最终的一致性保障。

四、分支事务最终处理(RM 响应 TC 指令)

场景 1:全局事务提交(TC 下发提交指令)

RM 接收 2.3 提交 指令后,执行 2.4 删除 undo-log,因为业务 SQL 已在一阶段提交,删除快照即可释放资源,标志分支事务彻底完成,全局事务达成最终一致。

场景 2:全局事务回滚(TC 下发回滚指令)

RM 接收 2.3 回滚 指令后,执行 2.4 恢复 log 数据,通过一阶段记录的 undo-log(数据快照),将业务数据回滚到修改前的状态,撤销一阶段的业务操作,保证全局事务的一致性。

TCC模式(高可用性,高耦合)

一、全局事务开启(TM 触发起点)

TM 执行 1.1 开启全局事务,标记分布式事务的起始,为后续跨微服务的分支事务提供统一的事务上下文,让 TC 和 RM 明确事务边界。

二、分支事务初始化(TM 调用 + RM 参与)

  1. TM 调用分支 :TM 执行 1.2 调用分支,触发微服务内的业务逻辑,此时微服务中的 RM 开始处理分支事务,进入 TCC 模式的核心流程。
  2. RM 注册分支事务 :RM 执行 1.3 注册分支事务,主动向 TC 登记当前分支事务,建立全局事务与分支事务的关联,使 TC 能够管理分支事务的状态。
  3. RM 报告事务状态 :RM 在完成分支事务的 Try 阶段后,执行 1.5 报告事务状态,将 Try 阶段的执行结果(成功或失败)反馈给 TC,TC 由此收集各分支事务的状态。

三、TCC 三阶段之 Try(RM 主导)

RM 执行 1.4 资源预留(Try),这是 TCC 模式的核心阶段:

  • 资源检测:检查业务操作所需的资源(如库存、余额等)是否充足;
  • 资源预留:冻结或锁定资源(如扣减库存预留量、冻结账户金额 ),确保后续 Confirm 或 Cancel 阶段可操作。
  • 关键约束:Try 阶段需保证 "幂等性"(重复调用不影响结果),且要为 Confirm/Cancel 阶段的执行做好准备。

四、全局事务二阶段决策(TC 主导)

  1. TC 检查分支事务状态 :TC 执行 2.2 检查分支事务状态 ,汇总各 RM 报告的 Try 阶段结果,判断全局事务的最终走向:
    • 所有分支事务的 Try 均成功 ,TC 向各 RM 发送 2.3 提交 指令,触发 Confirm 阶段;
    • 任意分支事务的 Try 失败 ,TC 向各 RM 发送 2.3 回滚 指令,触发 Cancel 阶段。
  2. TC 发起全局指令 :TC 执行 2.1 提交、回滚全局事务 操作,根据分支事务状态,统一向 RM 下发 Confirm 或 Cancel 指令,驱动各分支事务完成最终的一致性保障。

五、TCC 三阶段之 Confirm/Cancel(RM 执行)

场景 1:全局事务提交(TC 下发提交指令)

RM 执行 2.4 Confirm,此阶段需完成:

  • 资源操作落定:将 Try 阶段预留的资源真正执行(如扣减实际库存、转账到账 );
  • 幂等性保障:确保 Confirm 操作可重复执行(即使重试也不会重复扣减 / 增加资源 );
  • 关键约束:Try 成功后,Confirm 必须能成功执行(否则需通过重试、补偿保证最终一致性 )。

场景 2:全局事务回滚(TC 下发回滚指令)

RM 执行 2.4 Cancel,此阶段需完成:

  • 预留资源释放:撤销 Try 阶段的资源预留(如解冻库存、返还冻结金额 );
  • 幂等性保障:确保 Cancel 操作可重复执行(即使重试也不会重复释放资源 );
  • 作用:恢复业务数据到 Try 阶段前的状态,保证全局事务的一致性。

MQ分布式事务(高性能,实时性低)

你们采用哪种分布式事务解决方案?

  • 简历上写的微服务,只要是发生了多个服务之间的写操作,都需要进行分布式事务控制
  • 描述项目中采用的哪种方案(seata | MQ)
    1. seata 的 XA 模式,CP,需要互相等待各个分支事务提交,可以保证强一致性,性能差 银行业务
    2. seata 的 AT 模式,AP,底层使用 undo log 实现,性能好 互联网业务
    3. seata 的 TCC 模式,AP,性能较好,不过需要人工编码实现 银行业务
    4. MQ 模式实现分布式事务,在 A 服务写数据的时候,需要在同一个事务内发送消息到另外一个事务,异步,性能最好 互联网业务

分布式服务的接口幂等性如何设计?

token+redis

生成token 带token验证

分布式锁

回答

  • 幂等:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致
  • 如果是新增数据,可以使用数据库的唯一索引
  • 如果是新增或修改数据
    • 分布式锁,性能较低
    • 使用 token+redis 来实现,性能较好
      • 第一次请求,生成一个唯一 token 存入 redis,返回给前端
      • 第二次请求,业务处理,携带之前的 token,到 redis 进行验证,如果存在,可以执行业务,删除 token;如果不存在,则直接返回,不处理业务

你们项目中使用了什么分布式任务调度?

xxl-job路由策略有那些?

相关推荐
SmalBox12 分钟前
【渲染流水线】[几何阶段]-[顶点着色]以UnityURP为例
架构
Java中文社群1 小时前
抱歉!Java面试标准答案最不重要
java·后端·面试
VisuperviReborn1 小时前
react native 如何与webview通信
前端·架构·前端框架
uhakadotcom1 小时前
Dask 框架深入浅出教程
面试·架构·github
wjs20241 小时前
C++ 日期 & 时间
开发语言
终焉代码1 小时前
【C++】STL二叉搜索树——map与set容器的基础结构
开发语言·数据结构·c++
源代码•宸2 小时前
深入浅出设计模式——行为型模式之观察者模式 Observer
开发语言·c++·经验分享·观察者模式·设计模式·raii
Java小Y2 小时前
redis(2)-java客户端使用(IDEA基于springboot)
java·redis·intellij-idea
herderl2 小时前
【无标题】命名管道(Named Pipe)是一种在操作系统中用于**进程间通信(IPC)** 的机制
java·linux·服务器·嵌入式硬件·php
小五1272 小时前
数据科学与计算实例应用
开发语言·python