知行札记
专题技术实践通信协议实践HTTP 网络通信

响应缺失与请求重试

根据客户端所见、服务端可能状态与幂等契约决定重试行为。

客户端没收到响应时,服务端可能已经完成请求。可靠的重试判断需要同时处理通信结果和业务效果。

本页延续原技术解释案例中的设置更新场景,依据 RFC 9110 构造推演。本轮未向实际服务发送请求;下列事件表说明可能状态,不表示已经观察到某个服务的实现。

同一次失败,双方知道的信息不同

假设服务保存一项设置,客户端用 PUT 提交目标表示,将界面语言设为 zh-CN。资源路径、权限和请求体是这项接口的契约;服务器可能完成更新后,响应在客户端读到之前丢失。

事件客户端能够知道什么服务端可能状态
发出请求客户端开始或完成发送尚未收到、接收中、处理中或已完成
连接失败,未读到完整响应通信没有给出可用结果可能未应用,也可能已经应用
再发相同请求新请求已开始发送可能首次应用,也可能重复处理

超时和连接断开通常只能证明客户端没有及时得到结果。需要确认是否已经生效时,可以使用操作查询、版本读取或服务定义的状态接口;这些能力必须由具体契约提供。

幂等契约提供的重试条件

RFC 9110 §9.2.2 将幂等界定为:多次相同请求的预期服务端效果,与一次相同请求相同。PUT 和 DELETE 具有这种方法语义,安全方法同样幂等。标准允许在尚未读到响应而连接失败时,自动重试幂等请求。1

在构造的设置接口中,重复提交相同完整表示仍使设置成为 zh-CN。服务器可能执行两次、分别记日志、产生不同响应。例如第一次创建资源返回 201,第二次替换现有资源返回 200 或 204;这与预期效果的幂等性质相容。

接口实现仍要遵守声明的方法语义。如果把“余额减十元”“增加一次计数”伪装成同路径同表示的 PUT,客户端依赖标准方法语义重试就可能造成重复效果。文档应明确操作效果、相同请求的判定及副作用范围。

POST 与应用层去重

普通 POST 的方法语义不足以单独确定自动重试条件。RFC 允许客户端在知道该请求实际语义幂等,或能判定原请求没有被应用时作相应重试判断。1

一种应用契约是给操作分配幂等键,并由服务端保存键与处理结果。完整设计需要回答:

  • 键的作用域是否包含账户、路径和操作类型;同键不同请求体如何处理。
  • 并发重复请求如何协调,处理中的状态怎样返回。
  • 业务提交与去重记录能否一致落地,崩溃恢复后是否会重复执行。
  • 记录保留多久,过期键重新使用时有什么效果。
  • 返回的是原响应、当前资源状态还是“处理中”,客户端如何继续查询。

仅在请求头加一个名为 Idempotency-Key 的字段,并不自动取得这些保证。事务、唯一约束、队列与外部副作用都需要在接口实现中形成闭环。

重试策略还要处理负载和并发

重试有次数和总时长预算,等待应考虑退避、抖动与服务提供的 Retry-After。网络中断、限流、临时服务故障、输入错误和权限失败应按契约分别处理;对所有错误无限重试会扩大负载,并掩盖需要用户修正的问题。

幂等也不保证重复请求不会覆盖别人的后续修改。设置更新之间若存在并发,服务可以使用 ETag 与 If-Match 等前置条件检查版本。前置条件失败后,客户端应读取当前状态并重新决定操作,不能盲目重发旧表示。

操作结束的用户界面应区分“确定失败”“确定完成”“结果仍待确认”。断网时把尚不确定的操作直接显示为失败并允许重复点击,可能诱发第二次业务操作;显示完成也需要足够的服务端证据。

能够据此得出的判断

这个构造说明了响应缺失为何产生结果不确定性,以及幂等预期效果如何支持特定重试。实际服务能否去重、是否提交、错误怎样返回和等待多久,仍需接口文档、代码及运行记录支持。相同响应本身不能证明执行次数、日志或外部副作用相同。

Footnotes

  1. IETF,RFC 9110 §9.2.2 Idempotent Methods,幂等范围和自动重试条件;2026-10-05 核对。 ↩ ↩2

最后更新于

本页目录