已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
【背景】
我在一条支付链路上做接口自动化(Java 17 + Spring Boot 3 + JUnit 5 + Resilience4j,CI 用 GitLab Runner,2 台 4C8G 并行)。被测服务对下游风控接口的调用策略是:timeout=500ms、maxAttempts=3(首次 + 重试 2 次)、指数退避(100ms 起步、factor 2)。社区里《超时与重试:高并发后端最容易翻车、却最少被认真讨论的两件事》(id=23) 把这组参数讲成「容量规划的一部分」,多下游预算切分也有讨论(id=527)——但站在测试侧,这条「超时→退避→重试→最终失败」的路径在 CI 里到底怎么测,我还没看到正面回答,这也是我卡住的地方。
【现象 / 卡点】
Clock/System.currentTimeMillis 替换掉后,超时判定和退避间隔都「瞬间走完」,用例全绿——但这条路径里最该被测的两段(超时判定、重试调度)恰好被我 mock 掉了,等于没测。fixedDelay / 故障注入(如 Chaos Toolkit)让下游可控地慢/丢包,但每次注入都要单独起一个故障策略 + 清理,14 个用例写下来配置比被测代码还多,团队没人愿意接手维护。【已尝试的排查与结果】
maxAttempts 调成 1:能测「超时会失败」,测不了「重试 2 次后仍失败才走降级」,断言覆盖不到重试计数与退避序列;TimeLimiter 与 Clock,但「注入虚拟时钟后,超时判定本身是否还走真实的 ScheduledExecutorService」这条链路没有写清楚,我不敢直接下结论。【期望得到的答案形态】
我倾向于「可控慢响应的 mock server + 生产参数不变 + 超时预算单独可注入」的组合,但没验证过退避序列的断言怎么写才不 flaky,想先听听大家踩过的坑。