渠道后台显示同一笔支付通知重试 6 次,用户收到 6 条发货短信,仓库出了 6 张拣货单。乍看像缓存或者权限的锅,追下去往往不是。
curl -X POST http://127.0.0.1:8080/callback -d '{"code":"SUCCESS"}'
SELECT order_no,COUNT(*) c FROM delivery GROUP BY order_no HAVING c>1;
追下去是这么回事:第一次回调业务处理成功,但返回体写成了空字符串,渠道认定失败继续重试。处理逻辑没有幂等判断,每次都完整跑一遍。返回值和业务结果不一致,这种坑最难从日志里看出来。
「回调重试重复处理」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。
具体做法是,入口先按渠道事件 id 查处理记录 已成功就直接返回 success;返回体固定成渠道要求的 JSON 不要留空;业务落库和发消息挂在同一个幂等键下;把历史重复单按订单号人工合并。
验收就看一点,重发同一事件返回 success 但短信只发一条 拣货单数量不再增加。
