用户只问一次,为什么后台请求了三次?
先看整个问题
订单查询临时超时,客服可以再查;订单号写错了,再查十次也没用。创建售后工单时,如果服务端已经保存、网络却在回包前断了,直接重做还可能生成两张工单。
今天我们把“失败”拆开,建立 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 再把写操作的审批、幂等和恢复接起来。