回调地址上线后日志一片 200,看上去全部成功;月底对账发现有 22 条根本没出片。因为 200 只表示「我收到了」,不代表「任务成功了」。
一句话结论
回调处理要分成两件事:收和判。收的部分只做三件事——验签、落原始 payload、立刻返回 200;判的部分放到异步队列里做。这样才不会因为处理超时被对方重推,也才有地方统计真实成功率。我这次 240 条回调,HTTP 200 是 100%,但 payload 里成功只有 218 条,首次真实成功率 90.8%;按失败码分流重提后,最终 237 条出片,成功率 98.8%。重复推送 17 条,靠 task_id 唯一键全部去重。
这篇解决什么问题
三种情况最常见。一是看着回调全 200,以为流程没问题,直到业务方说某条片子一直没出来。二是回调处理里同步做了下载、转存、写库三件重活,耗时超过对方超时阈值,于是同一条被推了三四遍,产生重复记录。三是失败回调被当成成功入库,产物地址是空的,直到下游取用时才报错。
根子是同一个:把「收到回调」当成任务完成。实际回调只是一个通知,通知里既有成功也有失败,还有可能重复。真正要建的是三样东西:一张按 task_id 唯一的结果表、一套失败码分类、一个定时对账。文章把它固定成五步,做完得到一张可对账的结果表和一份按失败码统计的成功率。
开始前要准备什么
- 回调原始日志:把收到的 payload 原文整条存下来,别只存解析后的字段。失败码的语义、字段的增删,全靠原文回溯。
- 签名校验方式:多数回调带签名或时间戳,必须验。不验等于把写库权限开放给任何能构造 POST 的人。验签失败也要记日志,那是被扫描的证据。
- task_id 唯一索引:结果表上先建唯一键,再写代码。唯一键是最后一道防线,代码写错了它还能挡住重复。
- 失败码清单:先收集已知的失败码与含义,再定「可重提 / 终态」两分类。分类错了,重提只会重复失败。
具体怎么做
第一步:回调入口只做三件事,做完立刻 200
三件事:验签、把原始 payload 落一张 raw 表、返回 200。不做解析判定、不做下载转存、不调下游。理由是回调方通常只等几秒,超时就重推;你在入口里干重活,等于主动制造重复推送。我第一版在入口里同步下载产物(单条 3–8 秒),结果 17 条被重复推送,最多的一条推了 4 次。
这是我收到的一条异步回调(完整 payload、请求头、签名方式)。
请帮我做四件事:
1. 指出验签需要哪些字段、按什么顺序拼接,给出可执行的校验步骤;
2. 从 payload 里区分出「任务标识」「任务状态」「失败原因」「产物地址」四类字段,指出哪些可能为空;
3. 判断这个回调是否可能重复推送,如果可能,指出用什么做唯一键最稳;
4. 给出一个「入口只做三件事」的最小实现要点:哪一步可能抛异常、抛了要不要返回 200。payload 与签名说明:(粘贴)
第二步:建结果表,唯一键放 task_id
结果表字段:task_id(唯一)、本地任务号、状态、失败码、失败原文、产物地址、首次回调时间、最后更新时间、重提次数。写入用「存在则更新、不存在则插入」,不要用「先查再插」——两个回调同时到达时,先查再插必然写重。我这次的 17 条重复推送,如果只有唯一键没有 upsert,会产生 17 条重复行。
这是我的回调 payload 字段结构与本地提交台账(含远端 task_id)。
请帮我做三件事:
1. 设计回调结果表的字段与索引,说明为什么唯一键要放在 task_id 上而不是本地任务号;
2. 给出「重复回调到达」时的写入策略,比较「插入失败忽略」与「存在则更新」两种做法在这种场景下的差别;
3. 指出哪些字段应该保留历史(例如多次回调的状态变化),哪些只需保留最新值。字段结构:(粘贴)
第三步:把失败码分成三类,不按「成功/失败」二分
三分类才够用:可重提(素材下载超时、内部临时错误)、不可重提(内容审核不通过、参数不合法)、未知(没见过的码)。我这次 22 条失败里,素材下载超时 7 条、内容审核 11 条、时长超限 4 条。前两类里只有下载超时可以重提,重提后 7 条全部成功;审核不过的 11 条重提也是白费,改内容才有用。
这是我收集到的全部失败回调及失败码(含原文消息)。
请帮我做四件事:
1. 把失败码归成三类:可重提 / 不可重提 / 未知,逐条给归类理由;
2. 指出哪些码看起来相似但处理方式不同(例如都是「超时」,但一个是取素材、一个是内部处理);
3. 给出每一类的处理动作:重提、改输入后重提、转人工、直接丢弃;
4. 指出哪些码应该触发告警(不是单条失败,而是系统性问题)。失败码清单:(粘贴)
第四步:定时对账,找出「两边都没有」的
对账比的是三份数据:提交台账(我发出去的)、结果表(我收到的回调)、远端查询(按 task_id 主动查)。真正危险的差异是「远端已完成但我没收到回调」——这类任务在本地永远是「处理中」,不会有任何告警。我这次对账 240 条,找到 3 条这种:远端早就成功,回调因为地址临时不可达丢了。对账跑一次 5 分钟,值得每小时一次。
这是我的三份数据:提交台账、回调结果表、远端按 task_id 查询的结果。
请帮我做三件事:
1. 列出所有差异类型(本地有远端无 / 本地无远端有 / 状态不一致 / 时间异常),并给出每类的处理优先级;
2. 找出「远端已完成但本地无回调」的条目,这是最危险的一类,请单独列出;
3. 给一个对账脚本的判断逻辑:什么情况自动补写结果、什么情况只告警不动数据。三份数据:(粘贴)
第五步:出成功率,按失败码分组而不是只看总分
成功率至少三个数:首次成功率(第一次回调就成功的比例)、最终成功率(含重提)、按码分布。只看第一个会低估流程能力,只看第二个会掩盖「靠重提硬撑」的事实。我这次首次 90.8%、最终 98.8%,差的那 8 个点全是下载超时,说明问题在素材源的稳定性,不在生成环节。
这是我的回调结果表(含状态、失败码、重提次数、时间)。
请帮我做四件事:
1. 算出首次成功率与最终成功率,并说明差额主要来自哪一类失败码;
2. 按失败码给出分布表,指出占比最高的那一类应该从哪里改(上游输入、下游依赖、还是本流程);
3. 判断重提是否「有效」:重提后成功的比例是多少,低于多少就该停止重提改为人工;
4. 给三个应该长期监控的指标,以及各自的告警阈值。结果表:(粘贴)
实测记录
规模:240 条异步任务,回调为 POST + 签名校验,回调入口曾做过同步下载(第一版)。
- HTTP 与业务状态不是一回事:240 条回调全部返回 200,但 payload 里成功只有 218 条,首次真实成功率 90.8%。
- 失败码分布:内容审核 11 条、素材下载超时 7 条、时长超限 4 条,合计 22 条。
- 重提效果:7 条下载超时全部重提成功;11 条审核不通过与 4 条时长超限重提无效,改内容或改参数后成功 3 条,最终 237 条出片,成功率 98.8%。
- 重复推送:第一版入口同步下载(单条 3–8 秒),17 条被重复推送,最多一条推了 4 次;改为「落 raw + 立刻 200」后,重复推送降到 0。
- 对账缺口:三份数据比对发现 3 条「远端已完成、本地无回调」,原因是回调地址临时不可达。如果没有对账,这 3 条会永远停在处理中。
最容易错的 3 个地方
第一,把 HTTP 200 当成任务成功。这是最贵的一个误解。回调接口返回 200 只表示「这条通知我收到了」,任务本身可能是失败的、被审核拒的、参数不合法被退回的。所有业务判定都必须读 payload 里的状态字段,而且要知道失败时哪些字段是空的。判断方法:拿一批回调统计一下 payload 里状态字段的分布,如果 100% 都是成功,那多半是没在读那个字段。
第二,在回调入口里做重活。下载产物、转存、调下游、发通知,任何一步慢几秒,都可能超过对方的等待阈值,于是同一条被反复推送,而每一次推送你都在重复做那件重活。正确做法是入口只落原文并立刻 200,后续全部交给队列。这条纪律的收益不是「快」,是「不重复」。
第三,没有对账,只等回调。回调会丢——地址临时不可达、证书过期、对方重试次数用尽,任何一种都会让某条任务永远停在「处理中」,而你的监控只看失败率,看不到这类沉默的滞留。对账是唯一能捞出它们的手段,成本很低:按 task_id 主动查一遍,和本地比一下。
可复用的东西
回调入口三件事:验签、落原文、立刻 200。任何接收 webhook 的场景都能套,包括支付通知、审批回调、消息回执。
失败码三分类:可重提、不可重提、未知。二分会把「审核不过」和「下载超时」混在一起,前者重提一万次也没用。
三份数据对账:提交台账、结果表、远端查询。差异里最危险的是「远端有、本地无」,它不产生任何告警。
常见问题解答
回调接口都返回 200 了,为什么还会有任务没出片
因为 200 只表示这条通知被接收,不代表任务成功。任务本身可能审核不通过、参数不合法、依赖的素材下载失败,这些失败一样会发回调,HTTP 层同样是 200。我这次 240 条回调全是 200,读 payload 里的状态字段才发现只有 218 条成功,首次真实成功率是 90.8%。
回调处理为什么要放到异步,入口里直接做完不行吗
入口里做重活会超过对方的等待阈值,同一条回调就会被反复推送,而每次推送你都在重复做那件重活。我第一版在入口同步下载产物,单条 3 到 8 秒,17 条被重复推送、最多推了 4 次;改成落原文加立刻 200 之后,重复推送降到 0。
失败码为什么要分三类而不是二分
二分会把「素材下载超时」和「内容审核不通过」混成同一类「失败」。前者重提有用,我这次 7 条全部重提成功;后者重提一万次也是同样结果,只能改内容。所以我分成可重提、不可重提、未知三类,未知那类先告警不自动处理,等看清楚了再归类。
只等回调不做对账会有什么问题
回调会丢:地址临时不可达、证书过期、对方重试次数用尽,任何一种都会让任务永远停在「处理中」,而失败率指标看不到这类沉默滞留。我这次对账 240 条捞出 3 条「远端早就成功、本地没有回调」,没有对账它们永远不会被发现。对账成本很低,按 task_id 主动查一遍再比一次即可。
本网站的部分内容可能来源于网络或用户投稿,仅供大家学习与参考,如有侵权,请联系客服: hhxmw778 进行删除处理。
本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
教程如引导您添加微信或有另外收费服务,请自行甄别!
如遇充值环节或绑定支付账户或输入支付密码之类的异常步骤,建议停止操作!本站不对操作项目的损失负责!
本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现任何资源有问题请向站长举报下架
(手机微信用户建议用默认浏览器打开,可体验完整功能)
