全维风尚

您当前的位置:全维风尚 > 铭创达智能>

一笔任务发两遍,仓库账面就多一笔:WMS与滚筒式AGV之间的幂等设计

2026-10-29

一笔任务发两遍,仓库账面就多一笔:WMS与滚筒式AGV之间的幂等设计

滚筒式AGV与WMS对接,最容易被忽略的资产是任务号。一笔任务从生成到核销,任务号要在两套系统之间被传递、被重试、被等待、被确认。链路里任何一跳为了"稳妥"所做的重发,都可能让同一笔任务在对端出现两次,而双方通常都意识不到自己收的是同一笔。

这类异常在投产现场并不少见,形态也高度一致:波次下发后,账面比实物多出几笔,或者同一个工位被连续占用两次;翻日志时,同一个任务号赫然出现两条执行记录,却没有人能指认是哪一跳复制了它。定位难的原因在于,链路里每一跳都按自己的规则"正确"工作——消息队列在重投,调度在重试,控制器在补发,谁都不认为自己制造了重复。

这篇的范围很小:不谈接口功能,不谈状态对错,只谈任务号的唯一性,以及它会在三个节点上如何失守。

重试的本意是稳妥,结果常常是复制

一笔任务从WMS生成,到滚筒把货物送走,任务号至少要在五个位置停留:WMS的待发队列、消息队列、调度系统的任务队列、AGV控制器的执行队列,以及完成回报的报文里。每停留一次,就多一次被重发的机会。

联调阶段为什么测不出这类问题?联调是"发一条、回一条",脚本不会在收到应答后把同一笔再发一遍,接收端自然没有机会见识"同一个任务号第二次到达"长什么样。生产环境则相反,重投不是故障,是常态:消息队列消费超时后重投、调度请求未确认时重发、控制器离线重连后补报。每一跳的重试都打着"保证送达"的旗号,却没有一跳问过:对端是不是已经处理过了。

要堵住这一环,你可以做一件很具体的事:把链路图摊开,逐跳标注三个信息——失败后的动作是重投、重发还是放弃,重试的间隔和次数上限,以及重发时是否携带原任务号。任何一个"重发"只要不携带原任务号,就相当于凭空生成了一笔新任务;凡是"未收到确认就重发"的机制,都要追问一句对端会不会其实已经处理成功,如果会,就必须配套去重,而不是单纯把重试次数调大来显得更"稳妥"。

去重不是可选项,接收端得记住"这笔见过"

去重是幂等的落点。接收端收到一个任务号,先回答"这笔我见过没有",见过就直接返回历史结果,没见过才执行。这个回答要可靠,需要三件事同时成立:存在一张能查的记录,任务号在两次到达时长得完全一样,记录活得比重试间隔久。联调环境里,三件事往往一件都不满足。

最普遍的情况是连记录都不存在。联调时脚本一条条发,天然没有重复,去重逻辑从未被触发,也就没人发现它不存在。判断它存不存在很简单:把同一笔任务的报文原样发两遍,看第二遍有没有产生第二次执行——有,就说明去重缺失,这一条就能定性。

即便有记录,任务号也不一定可靠。两侧字段定义不完全一致,有的带前导零,有的带空格,有的报文里混入不可见字符。去重表里存的与报文里带的如果对不上,第二次到达的报文就查不到历史记录,去重形同虚设。所以去重键必须在写入前做规范化——去空格、统一大小写、固定长度,这一条要写进接口文档,而不是交给两边各自发挥。

最后是记录的存活时间。重试的间隔可能长达数分钟,去重表如果只保留最近几秒的记录,慢重投照样钻空子。窗口长度至少要覆盖链路里最长的重试间隔,而不是拍脑袋定一个值。

完成回报可以重复到达,核销只能发生一次

任务真正敏感的动作是核销:释放工位、扣减库存、把任务置为完成。这些动作一旦执行两次,账面和实物就永久性对不上,而且事后很难修——补账能补回数字,补不回已经被另一笔任务占用的工位。

重复核销的通道与重复下发一样多:完成回报在消息队列里被重投、在调度重试时被再次提交、在控制器补报时被再次发送。联调时"完成回报只到达一次"这个假设从没有被检验过,而生产环境里它恰恰是最不可靠的假设。

落到做法上,核销必须设计成"先查状态、再变更状态"的原子操作,而不是无条件的扣一笔。任务状态里"已核销"应当是终态,任何重复到达的完成回报命中终态时直接丢弃,返回"已处理",绝不再执行扣减。如果扣账是异步的,还要额外处理一个竞态:第一遍回报触发的扣账尚未完成,第二遍回报已经到了。此时要么按任务号加锁,要么让扣账动作本身具备幂等性——同一个任务号只允许扣一次,两者至少占其一。

验证这两条,只需要做两组重放:把同一完成回报连续发两遍,看账有没有变化;核销完成后再把迟到的旧回报发一次,看库存有没有被二次扣减。这两组用例要放进每次接口版本升级的回归范围,而不是只在初次对接时跑一遍。

三个节点指向同一件事:对接的可靠性,不体现在功能列表有多全,而体现在"同一笔任务无论经历多少次重试、迟到多久,都只会被处理一次"这条纪律上。任务号就是这条纪律的载体,谁在链路里复制了它,谁就要负责让接收端认出来。

下次再遇到账面和实物对不上,先别急着查网络、查硬件,先把任务号拉出来看一遍:同一笔是不是出现了两次。多数时候,答案就藏在这里。唯一性这件事不需要高深的技术,只需要有人在联调之外,真的把同一笔任务发两遍、把完成回报重放一遍,然后盯着账看有没有变化。做到这一点的项目,上线后半夜被叫起来的次数会少很多。

以上信息仅供参考,不能作为预防、诊断及医疗依据,就医请遵照医院诊断,在专业人士的指导下治疗。

全维风尚

全维风尚网是一个多维度视角下的综合信息聚合门户。我们致力于为您捕捉实时社会热点、前沿科技数码、潮流生活指南及全行业动态。看大千世界,触时代风尚,获取高价值综合资讯就上全维风尚网...【详情】