用户只问一次,为什么后台请求了三次?

先看整个问题

订单查询临时超时,客服可以再查;订单号写错了,再查十次也没用。创建售后工单时,如果服务端已经保存、网络却在回包前断了,直接重做还可能生成两张工单。

今天我们把“失败”拆开,建立 Harness Engineering(执行控制工程)的第一道边界:谁可以重试、最多几次、等多久、怎样停。SDK 能帮忙发请求,不能替我们做业务判断。

一次重试要先回答什么

情况先判断本课处理
参数错、401 无权限、402 额度问题重新发送会改变输入或权限吗停止并修正,不自动重试
明确只读查询临时不可用是否还有总时间、次数和费用预算可以有限重试
用户已取消是否还应继续为旧请求工作停止,不提交迟到结果
写操作结果未知服务端是否已经执行成功先用业务 ID/幂等键查状态,再决定恢复

这里的 Idempotency(幂等)指同一业务请求重复到达,仍只产生一次预期业务效果。仅生成一个随机字符串不等于服务端实现了幂等。

用最小例子观察

在自己的项目里定义 read_with_retry(operation)。operation(remaining_timeout) 每次接收剩余时间,并把它传给 HTTP 客户端;返回成功结果,或抛出已经分类的临时只读错误。不要把所有异常都捕获后继续循环。

控制顺序:检查取消 → 检查剩余时间 → 调用 → 分类结果 → 必要时退避 → 再检查。

先预测四种情况的调用次数,再看老师运行:正常 1 次;前两次暂时失败、第 3 次成功;参数错 1 次后停止;调用前已取消则 0 次。这是固定故障注入,不是在测某个真实 Provider 的稳定性。

Backoff(退避)让失败后稍等再尝试。本实验用 0.1、0.2 秒便于复现;实际策略还应看 Retry-After(服务端建议等待时间)、随机抖动与业务时限,不能全班照抄成生产参数。

回答预习的问题

用户问一次,SDK 重试和我们自己的重试可能叠加。假设外层最多 3 次、内层每次又最多 3 次,最坏可能产生 9 次请求。课堂模型调用仍关闭 SDK 自动重试,不把这个只读实验直接套到付费模型或写操作。

总时间预算也不能靠“每次 timeout=30”替代:那可能等 90 秒。每次都传剩余时间;忽略 timeout 的同步函数不能被这个循环强制终止,需要底层客户端配合。

收回到项目与面试

让 AI 为你的只读查询建议重试策略,只允许改这一层。你负责审核:错误分类、次数、总时间、取消和日志是否一致。独立加一个“结果到达时已经超时”的反例,不能放宽时间让测试变绿。

面试回答顺序:业务副作用 → 错误类型 → 时间/次数预算 → 停止条件 → 如何证明没有重复执行。今天留下错误分类和测试,W07/W08 再把写操作的审批、幂等和恢复接起来。