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

目录

限流

为什么要限流?

限流的实现方式:

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路由策略有那些?

相关推荐
落日沉溺于海8 分钟前
React From表单使用Formik和yup进行校验
开发语言·前端·javascript
知识分享小能手10 分钟前
React学习教程,从入门到精通, React 新创建组件语法知识点及案例代码(11)
前端·javascript·学习·react.js·架构·前端框架·react
江团1io018 分钟前
微服务雪崩问题与系统性防御方案
微服务·云原生·架构
快乐肚皮21 分钟前
fencing token机制
java·fencing token
叶落阁主30 分钟前
Neovim 插件 i18n.nvim 介绍
java·vue.js·vim
渣哥31 分钟前
让集合线程安全的几种靠谱方法
java
LDelon31 分钟前
iOS GitSubModule CocoaPod 制作私有源本地组件库
架构
dylan_QAQ33 分钟前
Java转Go全过程06-工程管理
java·后端·go
鲸屿1951 小时前
python之socket网络编程
开发语言·网络·python
小毛驴8501 小时前
所有微服务部署都使用一个git地址,并且通过docker部署各个服务的情况下,如何编写mvn指令来处理各个服务。
git·docker·微服务