← 返回题目列表

HTTP 请求重试为什么要考虑幂等性?哪些请求可以安全重试?

中等 第 25 / 32 题 更新于 2026/08/02
HTTP幂等性重试

简化版

HTTP 请求重试必须考虑幂等性,因为网络超时不代表服务端一定没处理。

如果客户端对非幂等请求盲目重试,例如重复创建订单、重复扣款,就可能造成业务副作用。

通常 GET、HEAD、PUT、DELETE 从语义上更适合重试;POST 默认不幂等,除非业务引入幂等键、唯一约束、请求去重等机制。

详细版

网络调用失败有很多状态:

请求没发出去
请求发出但服务端没收到
服务端收到并处理了,但响应丢了
服务端处理中超时

客户端看到的可能都是 timeout。

如果它直接重试 POST /orders,可能创建 2 个订单。

所以重试策略要区分请求语义:

  • 查询类请求通常可重试。
  • 覆盖式更新通常可重试。
  • 创建、扣款、发券等操作必须设计幂等。

常见方案是给请求带 Idempotency-Key,服务端用这个 key 识别重复请求并返回同一结果。

完整版教学

1. 先说明为什么超时最危险

调用方看到 timeout 时,最麻烦的是不知道服务端到底做了什么。

可能出现 4 种情况:

1. 请求根本没发出
2. 请求到达代理但没到应用
3. 应用处理成功但响应丢失
4. 应用仍在处理,客户端先超时

这些在客户端都可能表现为失败。

重试的难点不是重新发送请求,而是不确定第一次请求是否已经产生副作用。

2. HTTP 方法语义和重试关系

HTTP 规范里有安全性和幂等性概念。

安全方法不应改变服务端资源。

幂等方法表示执行 1 次和执行多次的最终效果相同。

方法通常是否安全通常是否幂等重试建议
GET可重试,但注意缓存和限流
HEAD可重试
PUT通常可重试
DELETE通常可重试,但看业务实现
POST默认谨慎
PATCH不一定视补丁语义决定

注意这是 HTTP 语义层的约定,业务实现仍然可能破坏它。

3. POST 为什么默认不能盲目重试

POST /orders 常表示创建订单。

如果第一次请求已经创建成功,但响应在网络中丢失,客户端重试后可能再次创建。

伪代码问题如下:

client -> POST /orders -> server 创建订单成功
server -> response 丢失
client timeout
client retry POST /orders
server 再次创建订单

这会导致重复订单、重复支付、重复发券、重复发送短信。

所以 POST 需要业务幂等设计。

4. Idempotency-Key 是常见方案

客户端为一次业务操作生成唯一 key:

POST /payments HTTP/1.1
Idempotency-Key: pay-20260802-0001
Content-Type: application/json

服务端处理逻辑:

  • 第一次看到 key,执行业务并记录结果。
  • 再次看到同一个 key,不重复执行业务。
  • 返回第一次处理结果或可识别的幂等响应。

这个 key 应该和用户、接口、业务参数绑定,不能全局随便复用。

5. 服务端幂等的常见实现

常见实现方式有:

  • 唯一索引,例如订单号唯一。
  • 幂等表,记录请求 key 和处理状态。
  • 分布式锁,避免并发重复处理。
  • 状态机校验,例如只有待支付才能扣款。
  • 去重缓存,短时间内过滤重复请求。
  • 消息消费端用业务唯一键去重。

强业务场景通常会组合多种手段。

单靠前端禁用按钮不是幂等。

6. 重试策略还要考虑退避和状态码

即使请求可重试,也不能无限重试。

工程上通常会做:

  • 最大重试次数,例如 2 到 3 次。
  • 指数退避,避免雪崩。
  • 只对网络错误、连接重置、502503504 等临时错误重试。
  • 400401403 这类确定性错误不重试。
  • 加请求超时和总截止时间。

重试是可靠性工具,也可能放大流量。

7. 常见误区与追问

  • 误区:HTTP 超时说明服务端没有执行。 超时只能说明客户端没及时拿到结果,服务端可能已经处理成功。
  • 误区:POST 永远不能重试。 POST 可以在业务幂等设计后安全重试。
  • 误区:GET 一定没有副作用。 规范语义上应安全,但实际系统可能有埋点、计数等副作用。
  • 追问:Idempotency-Key 应该存多久? 要覆盖客户端可能重试的时间窗口,支付等场景通常要更长。
  • 追问:DELETE 重试为什么通常可接受? 删除同一资源多次的最终状态通常都是资源不存在。
  • 追问:重试为什么可能造成雪崩? 大量客户端同时重试会放大后端压力。

8. 加强记忆

重试题的核心链路是:失败不等于未执行,重试必须看幂等,非幂等操作要有业务去重。

面试里把“方法语义 + 业务幂等 + 退避策略”讲全,就很扎实。