重复提交从哪里来
自助交付中的重复提交极易发生:用户重复点击、请求超时后重试、脚本与流水线重跑,都会让同一请求被执行多次,导致重复创建资源、重复占用配额、重复变更配置。防护的核心是幂等设计:请求携带唯一标识,服务端先判断该请求是否已处理,再决定执行还是直接返回既有结果。
基本信息
| 识别方式 | 由客户端生成的请求唯一标识 |
|---|---|
| 处理策略 | 相同标识只执行一次并返回首次结果 |
| 保留期限 | 标识需保留到超过最长重试窗口 |
| 并发处理 | 同一标识的并发请求进入同一处理链路 |
| 替代方案 | 按资源名幂等创建,已存在则视为成功 |
典型使用场景
- 界面重复点击:提交后按钮失活并携带请求标识,避免二次创建
- 超时重试:客户端超时后重发,服务端凭标识返回首次结果
- 脚本与流水线:自动化脚本重跑时不应产生第二份资源
- 并发冲突:同一标识同时到达时,后到者等待或复用首份结果
- 外部回调:交付完成通知可能重复送达,处理逻辑需按标识去重
重复来源与防护
| 重复来源 | 表现 | 防护方式 |
|---|---|---|
| 用户重复点击 | 短时间内两次相同请求 | 请求标识加界面防抖 |
| 客户端超时重试 | 同一请求多次到达 | 幂等键加服务端去重 |
| 流水线重跑 | 整批任务再次执行 | 按资源名幂等创建 |
| 回调重复投递 | 完成通知多次送达 | 事件标识去重 |
幂等键的最小实现
幂等键的最小实现
# 1. 客户端为每次提交生成唯一标识,重试时沿用同一个标识
# 2. 服务端先查该标识是否已处理:已处理则直接返回既有结果
# if request_id in processed: return stored_result
# 3. 未处理则进入执行,并在同一次登记中保存标识与结果
# 4. 标识保留时间需覆盖最长重试窗口,避免过期导致重复执行
# 5. 同一标识的并发请求应排队处理或复用同一执行结果幂等与去重需要分清:幂等保证同一请求重复提交不产生额外副作用,去重只是丢弃重复请求。前者在重试场景更可靠,因为客户端仍能拿到明确的执行结果。
请求标识的保留时间必须覆盖客户端最长重试窗口。过早清理标识会让重试被当作新请求,重复创建资源;对于占用配额或产生费用的交付,这类重复通常需要人工清理。