← 每日面试题 学习看板

如何解决接口幂等的问题?

面试题/02架构设计题/02分布式/07接口幂等与安全/如何解决接口幂等的问题?.md

面试记录 2026-10-10

题目:如何解决接口幂等的问题?

难度:medium

标签:arch/distributed/idempotent, architecture/idempotent, difficulty/medium

评分:⭐⭐⭐☆☆(3/5)

我的回答

首先确定一下接口幂等的概念。接口幂等本质上就说防止用户反复的提交相同的请求,哪怕是误触也好,是刷机也好,要处理类似的这种请求,误触、重试都有可能产生幂等性的问题,我们要处理的就是这种问题。

然后知道了要处理的问题是什么,然后就开始考虑怎么去实现。首先是要识别这个请求是重复的,一个是通过时间,连续的、短暂的连续时间内同样的请求,然后是请求内容,同样的请求去识别出你这个请求是重复的,而不是说常规的、正常的请求,识别出是重复请求之后,再进行对应的处理。

业务处理上,常规要么就是把前置的处理掉,然后直接快速返回,你已经重复提交过了,或者是返回,直接返回一个正常的请求结果,因为前面已经有提交的了。

这一套下来,基本上就一个常规的幂等接口幂等的方案。

另外常见的一些处理幂等的方式,比如说像订单的状态机,就是一个处理幂等的方式。一个订单只能从一个状态往下一个状态走,你继续用上一个状态的请求过来,是达不到正常的结果的。

另外就是还有,比如说像查询,它自身本身就是幂等的,并不需要做什么幂等性的处理,只需要做频度的限制。

而对于前置刚刚说的重复数据的识别,一般使用的方案是对请求的入参进行哈希处理,然后判定当前的请求是否连续请求过,然后另外加缓存,缓存去判定这个请求是否短时间内重复的请求了。如果判定是的,就判定它是一个不合理的请求,然后这时候给它进行打回,或者是给它一个已经处理完毕,或者你重复请求了的一个异常反馈。这就是我对幂等问题处理的方案。

点评

优点:

不足:

补充:

完整讲解

第一部分:知识重点剖析

核心考点定位:考察对幂等的多层次理解——接口层、业务层、存储层各自的实现方式与取舍。

知识点拆解:

  1. 幂等定义:多次相同请求的效果与一次相同请求的效果相同。核心是"结果一致",而不是"处理次数一致"
  2. 哪些操作天然幂等:GET/PUT/DELETE 天然幂等;POST/PATCH 非幂等,需要额外机制
  3. 接口层幂等(前置过滤):
  1. 业务层幂等:
  1. 存储层幂等:
  1. 分布式下的坑:多实例并发时,光有 Redis SETNX 不够,还需要 DB 唯一索引兜底(Redis 与 DB 不共享事务)
递进:定义 → 天然幂等/非幂等 → 三层方案 → 分布式坑 → 综合实践

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. 为什么不用数据库唯一约束做幂等控制?
  1. Redis SETNX 做幂等,如果 Redis 挂了怎么办?
  1. 支付场景的幂等怎么设计?
  1. 幂等 vs 防重 vs 限流的区别?

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,接口幂等的本质是"多次相同请求产生的效果和一次请求相同"。像 GET、PUT 天然幂等,POST 通常非幂等需要额外设计。我的做法是分层建设三层防线。

第一层是接口层幂等,用 Token 模式或 Idempotency-Key 请求头。Token 模式是客户端先向 /token 接口申请一次性凭证,服务端存 Redis 并设置过期时间;业务请求携带 token,服务端用 SET NX EX 原子操作消费 token,消费成功才继续处理业务。这样重复请求因为 token 已被消费而被直接拦截,不会重复执行。对于支付等关键场景,可以强制要求客户端生成 pay_request_no 作为幂等 key,全链路带此 key。

第二层是业务层幂等,通过状态机约束。比如订单只能从"待支付"推进到"已支付",重复的支付请求因当前状态已经不是"待支付"而被业务逻辑拒绝,返回业务错误码但不会二次扣款。业务唯一键也是这一层的关键,像订单号、支付流水号这些业务侧的自然唯一标识,可以贯穿全链路。

第三层是存储层幂等,用数据库唯一索引兜底。即使前两层都失效了,比如 Redis 宕机或业务代码有 bug,DB 唯一索引也能阻止脏数据写入。比如订单表加 UNIQUE KEY (order_no, pay_channel),重复支付请求会因唯一约束冲突被拒绝。工程实践上常用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE 让唯一冲突变成软失败。

分布式下有个常见坑:Redis 与 DB 不共享事务,光有 Redis SETNX 不够,必须 DB 唯一索引兜底。另外区分一下:幂等是业务语义层要求(多次请求效果一致),防重是接口层要求(拒绝短时间重复),限流是流量层要求(控制并发)。三者互补而不是替代。

在实际工程里,一次完整的支付幂等设计会同时用到 Token + 业务唯一键 + 状态机 + 唯一索引四层,任何一层都能兜住不同失败模式。这也体现了幂等不是一个点,而是一套纵深防御体系。