接口防重提交 ≠ 接口幂等性
目录
一、先搞懂两个核心概念
1. 接口防重提交(前端 / 网关层)
2. 接口幂等性(服务端核心)
3. 重试机制
二、为什么生产环境不能只靠「防重提交」?
三、正确的生产架构:三者配合使用
1. 前端 / 网关:防重提交(第一道防线)
2. 服务端:幂等性(最终兜底防线)
3. 重试机制(必须配合幂等)
四、最终结论(生产标准回答)
生产环境标准方案:
一句话总结
总结
接口防重提交 ≠ 接口幂等性,二者不是二选一,而是互补关系:
- 防重提交:前端 / 网关层的短期拦截(防重复点击、网络抖动重复请求)
- 幂等性:服务端核心保障(保证无论调用多少次,结果都只生效一次)
- 重试机制:配合幂等性,让系统自动容错、高可用
一、先搞懂两个核心概念
1. 接口防重提交(前端 / 网关层)
作用:拦截重复请求,不让重复请求到达后端。实现:
- 前端:按钮点击后禁用、生成唯一请求 ID(token)
- 网关 / 拦截器:根据唯一 ID 短时间内拒绝重复请求局限:
- 只能防短时间、简单重复
- 网络超时、重试、MQ 重发、故障恢复防不住
- 绝对不能作为生产环境唯一保障
2. 接口幂等性(服务端核心)
定义:同一个请求执行 1 次和执行 N 次,效果完全一样,不会重复扣款、重复下单、重复插入数据。这是生产环境必须保证的底线。
3. 重试机制
作用:网络超时、服务抖动时自动重试,提升成功率。前提:必须先保证接口幂等,否则重试 = 灾难。
二、为什么生产环境不能只靠「防重提交」?
只做防重,会遇到这些生产级故障:
- 网络超时重试:前端没收到响应自动重试,防重失效
- MQ 重试:消息队列默认重试,防重完全拦不住
- 网关 / 服务重启:临时防重缓存失效,重复请求直接穿透
- 分布式场景:多实例部署,防重缓存不同步
- 回调 / 异步通知:第三方支付、支付回调重复触发
只做防重 = 埋雷,数据一致性一定会出问题。
三、正确的生产架构:三者配合使用
前端防重(按钮禁用+请求ID) ↓ 网关/拦截器 防重提交(短期去重) ↓ 服务端 【幂等性保障】(核心兜底) ↓ 配合 【重试机制】(自动容错)1. 前端 / 网关:防重提交(第一道防线)
- 点击后禁用按钮
- 请求前获取唯一
requestId - 网关层 1 秒内相同
requestId直接拒绝
2. 服务端:幂等性(最终兜底防线)
Java 生产最常用 3 种幂等方案:
- 唯一索引 / 唯一约束(最简单)
- 订单号、业务流水号建唯一索引
- 重复插入直接报错,数据库兜底
- 分布式锁(Redis)
- 以
业务唯一ID加锁 - 解锁前,相同请求直接返回 “已处理”
- 以
- 状态机判断
- 订单状态:待支付 → 支付中 → 已支付
- 已支付订单,再次收到支付请求直接返回成功
3. 重试机制(必须配合幂等)
- Feign/RestTemplate 超时自动重试
- 重试次数:2~3 次即可
- 只有读接口、幂等写接口才能重试
四、最终结论(生产标准回答)
生产环境标准方案:
- 必须实现接口幂等性(核心,保证数据安全)
- 必须配合重试机制(提升系统可用性)
- 接口防重提交作为辅助优化(减少无效请求)
一句话总结
防重是节流,幂等是兜底,重试是容错。生产环境:接口幂等性 + 重试机制 = 标配;防重提交 = 锦上添花。
总结
- 不要二选一:幂等 + 重试是必须,防重是辅助
- 只做防重必出事故:网络重试、MQ、分布式场景都会穿透
- 生产标准:前端防重 → 网关去重 → 服务幂等 → 安全重试
