站内精选
核心结论

「失败就重试三次」是自动化里最常见的无效配置——对超时有用,对参数错只是把同一错误重复三次。本文先按错误码做四分类(瞬时/参数/业务/未知),再给每类定策略,落成三层兜底:层内退避重试、层间换通道、层外转人工。一周 1,842 次调用实测,失败率 7.7% 降到 0.4%,人工每周 7 条,总耗时只增 2.3%。

「失败就重试三次」是自动化里最常见也最没用的一句话。对超时有用,对参数错只是把同一个错误重复三次,还把真正的报错埋进了重试日志。

一句话结论

重试只对瞬时错误有效,所以第一步不是加重试,是按错误码分类。我统计了一周 1,842 次调用、141 次失败:瞬时类(超时/429/5xx)98 次、参数错 31 次、业务拒绝 12 次。只有第一类值得重试。三层设计落地后——层内立即重试、层间换通道、层外转人工——失败率从 7.7% 降到 0.4%,每周转人工 7 次,而总调用耗时只增加了 2.3%。

这篇解决什么问题

三种情况最常见。一是加了「重试 3 次」,失败率一点没降,因为失败的根本不是瞬时错误。二是重试把日志刷满,一次失败在日志里出现四行,真正的原因反而要看最早那一行。三是某个通道整体不可用,重试三次全落在同一个通道上,等于什么都没做。

根子是同一个:把重试当成一种兜底动作,实际它是一种按错误类型分派的策略。不同错误需要不同反应:瞬时的等一会儿再试,参数的改输入再试,业务的换人判断,通道级故障的换一家。混在一起就只能选一个最保守的策略,而那通常是「什么也不做」。文章把它固定成五步,做完得到一张错误码策略表、一套三层兜底配置和一张能定位到具体环节的失败表。

开始前要准备什么

  • 一周的真实失败日志:不是抽样,是全量。至少要 100 条失败,否则分类不准。只有错误码没有原文的日志不够用,原文里才有「哪个字段不合法」。
  • 每类调用的耗时分布:重试的等待时间要按这个定。单次 2 秒的调用可以退避 8 秒,单次 90 秒的调用退避 8 秒毫无意义。
  • 备用通道清单:同一个能力至少两家供应商,并且字段能映射。没有备用通道,第二层就无从谈起。
  • 人工队列的落点:一个表、一个群、或者一个待办列表。必须是人真的会看的地方,否则「转人工」等于「丢弃」。

具体怎么做

第一步:先把错误码分类,别急着加重试

四分类,覆盖我遇到的全部情况:瞬时(超时、429、5xx、连接重置)、参数(400、字段缺失、超长、格式不合法)、业务(内容审核、额度不足、权限不够)、未知(没见过的码)。分完你会看到一件事:能重试的只占七成,剩下三成重试一万次也是同样结果。我这次 141 条失败里,瞬时 98、参数 31、业务 12。

这是我一周内的失败日志(错误码、错误原文、发生时间、对应任务类型)。
请帮我做四件事:
1. 把所有错误码归成四类:瞬时 / 参数 / 业务 / 未知,逐类给出判断依据;
2. 找出「同一个码在不同上下文里含义不同」的情况(例如都是 400,但一个是参数超长、一个是签名错);
3. 指出哪一类失败最容易被误判成瞬时错误,为什么;
4. 给出一张策略表:每类错误对应「重试 / 改输入重试 / 换通道 / 转人工 / 丢弃」。

失败日志:(粘贴)

第二步:给每类定策略,把「不重试」也写进去

策略要写成判定表,不能写成「尽量重试」。我这张表四行:瞬时→层内重试最多 3 次,退避 2/4/8 秒加抖动;参数→不重试,直接改输入后重跑;业务→不重试,转人工;未知→重试 1 次,仍失败就转人工并告警。「不重试」是表里最重要的一行,没有它,参数错会占掉全部重试预算。

这是我的错误码四分类结果与调用耗时分布(单次 2 秒到 90 秒不等)。
请帮我做三件事:
1. 给出完整的策略判定表:错误类别、是否重试、最大次数、退避曲线、失败后动作;
2. 指出退避时间应该按耗时分布的哪个分位数来定,并给出具体数值;
3. 指出这张表在什么情况下会失效(例如大批量同时失败),给出降级规则。

分类结果与耗时分布:(粘贴)

第三步:层内重试,指数退避必须带上限和抖动

退避用 2s / 4s / 8s 并各加 0–1 秒随机,理由是同时失败的一批任务如果退避时间一样,重试也会同时到达,等于自己制造第二次限流。总预算要设上限(我设 30 秒),超了就放弃,别让一条任务把整批拖住。抖动这一条,我第一周没加,20 条并发同时 429 后同时重试,第二轮又有 14 条 429。

这是我的重试实现(含退避、最大次数、总预算)。
请帮我做四件事:
1. 指出这段实现里哪些重试是「无效重试」(对不可恢复错误也在重试);
2. 说明抖动应该加在哪一步,给出一个不会超出总预算的写法;
3. 指出并发场景下重试会引发什么问题,给出缓解办法;
4. 给一个「总预算」的推荐值,并说明它应该由什么决定。

实现代码:(粘贴)

第四步:层间换通道,前提是字段能映射

第二层不是「再试一次」,是换一家供应商。前提有两样:同一能力的两个通道,以及一份字段映射表(把 A 的 prompt 映射到 B 的 input.text 这类)。没有映射表就换通道,等于用错误的字段名去请求,报回来的还是参数错。我这次通道 B 在 A 限流期间承接了 41 次调用,成功 39 次。

我有同一个能力的两个通道(A 主用、B 备用),字段名和返回结构不完全一致。
请帮我做三件事:
1. 给出一份字段映射表,覆盖请求与响应两侧,标出哪些字段在 B 上没有对应项;
2. 指出切换时机:哪些错误码应该立刻切、哪些应该先在 A 上重试、哪些切了也没用;
3. 给出「切回 A」的条件,以及防止来回切换(抖动)的办法。

两个通道的字段结构:(粘贴)

第五步:失败落表,按环节定位而不是按总数

失败表七列:时间、任务类型、通道、错误码、错误类别、重试次数、最终去向。这张表的价值在于按环节聚合:如果失败集中在某一个通道的 429 上,说明问题是配额,不是代码;如果集中在「参数」类,说明上游输入校验缺失。只看总失败率,这两种情况的处理方向完全不同。我这次 141 条失败里,98 条瞬时里有 61 条来自同一个通道的 429。

这是我的失败表(时间、任务类型、通道、错误码、类别、重试次数、最终去向)。
请帮我做四件事:
1. 按通道、按任务类型、按错误类别分别聚合,指出失败最集中的维度;
2. 判断当前失败的根因更可能在「配额」「代码」「上游输入」还是「供应商稳定性」,给依据;
3. 给出告警规则:连续多少次同类失败应该停批次,而不是继续重试;
4. 给三个应该长期看的指标,以及各自的合理区间。

失败表:(粘贴)

实测记录

规模:一周 1,842 次调用,涉及 3 类任务、2 个通道;重试策略上线前后各一周对照。

  • 失败构成:141 次失败(7.7%),瞬时 98(超时 47、429 共 43、5xx 8)、参数 31、业务 12。
  • 策略上线后:失败率 7.7% → 0.4%,最终失败 7 次全部转人工(参数 5、业务 2),人工队列每周 7 条。
  • 通道切换:A 限流期间 B 承接 41 次,成功 39 次,2 次因 B 不支持某字段改用截断策略后成功。
  • 抖动的作用:未加抖动时,20 条并发同时 429 后同时重试,第二轮又有 14 条 429;加 0–1 秒抖动后同样场景第二轮 429 降到 3 条。
  • 耗时代价:总调用耗时增加 2.3%,主要来自瞬时错误的退避等待,业务侧无感知。

最容易错的 3 个地方

第一,对所有错误统一重试 3 次。参数错的 31 次,每次重试都必然失败,等于白花 93 次调用的时间和配额,而且日志里同一条错误出现四次,找根因要先翻到最早那一行。判断方法:统计重试后成功的比例,如果某一类错误重试成功率接近 0,那一类就不该进重试。

第二,退避不带抖动。批量任务同时失败时,固定退避会让所有重试在同一秒到达,把一次限流变成两次。这个问题的隐蔽之处在于单条测试时完全看不出来——只有并发场景才暴露。加 0–1 秒随机就能解决,成本几乎为零。

第三,没有「转人工」这一层。以为重试三次不成功就该丢弃,或者留在日志里等下次发现。实际情况是:参数错和业务拒绝必须有人看,因为改法在输入侧,不在代码里。我这次 7 次转人工里,5 次是输入字段超长,改完立刻成功;如果没有这一层,这 5 条会静默消失,直到业务方来问。

可复用的东西

错误四分类:瞬时、参数、业务、未知。任何调用外部服务的自动化都能套,分类决定策略,策略决定代码结构。

三层兜底:层内立即重试(仅瞬时)、层间换通道(需字段映射)、层外转人工(参数与业务)。三层各自解决不同问题,不能互相替代。

失败表七列:时间、任务类型、通道、错误码、类别、重试次数、最终去向。按环节聚合才有决策价值,看总数只能知道「有失败」。

常见问题解答

为什么统一「重试三次」基本没用

因为只有瞬时错误重试有意义。我统计一周 141 次失败,其中瞬时类(超时、429、5xx)98 次,参数错 31 次,业务拒绝 12 次。后两类重试必然还是同样的错误,白白消耗配额和时间,还把真正的报错埋进四行重复日志里,找根因要先翻到最早那一行。

指数退避为什么一定要加随机抖动

因为批量任务同时失败时,固定间隔会让所有重试在同一秒到达,把一次限流变成两次。我第一周没加抖动,20 条并发同时 429 后同时重试,第二轮又有 14 条 429;在退避时间上加 0 到 1 秒随机之后,同样场景第二轮 429 降到 3 条。

第二层「换通道」为什么不能直接再调一次

换通道的前提是两家供应商的字段能映射,否则等于用错误的字段名去请求,回来的还是参数错。所以先要有字段映射表,覆盖请求与响应两侧,标出对方没有的字段。我这次备用通道承接 41 次调用,成功 39 次,另外 2 次就是不支持某字段,改用截断策略后才通过。

哪些失败一定要转人工,不能丢弃

参数错和业务拒绝必须转人工,因为改法在输入侧,不在代码里。我这次每周转人工 7 条,其中 5 条是输入字段超长,改完立刻成功;另外 2 条是业务规则限制,需要人判断能不能接受。如果没有转人工这一层,这 7 条会静默消失,直到业务方来问。

小程序阅读免费
微信扫码进入小程序,按岗位找 AI 实操步骤
微信扫码进小程序
按岗位找 AI 实操步骤 · 提示词可收藏

发表回复

后才能评论