去年冬天,我带团队去给华东一家做进口牛肉冷链的客户做系统改造。他们老板有个很朴素的想法:仓库里每人发台工业PDA扫码枪,一台两三千块,摔了坏了心疼,系统升级也麻烦。现在人人都有智能手机,能不能弄个微信小程序,打开就扫,手机直接当扫码枪用?
这需求听起来像小学生作业,但真做起来,软件系统架构上的弯弯绕绕,足够让一堆号称“全栈”的团队栽跟头。尤其是冷链物流这个场景,对通信延时的苛刻程度,远超普通电商仓。
先说为什么不能简单做个H5页面调调摄像头。冷库环境温度常年零下18度,手机贴膜容易起雾,这个硬件层面我们管不了,但软件层面,最要命的是作业节奏。分拣员推着车,左手拿手机,右手搬箱子,扫一个码,系统必须立刻告诉他“这箱是2023批次、需放B区、-18度完好”,如果界面转圈圈超过半秒,后面的人就堵上了。我们实地测过,传统基于HTTP短连接的REST接口,在冷库铁皮货架林立的环境下,4G信号来回穿透衰减,一次请求响应经常飙到700-1000毫秒,工人直接扔手机。更麻烦的是,冷链扫码不是单纯查库存,还得实时拉取温湿度传感器的历史曲线,确认这批货没脱温。多个数据源聚合,延时高了根本玩不转。
所以低延时通信方案,是我们整个架构设计的核心命门。
我们最终落地的方案,是一套“端侧轻队列 边缘加速 云中心幂等”的三角架构。这里头有几个关键决策,都是交了学费换来的。
有个坑是微信小程序的网络连接机制。手机小程序坚决不能用HTTP轮询,我们直接上了WebSocket长连接。但很多人不知道,小程序在切后台或者锁屏后,系统会干掉长连接。冷链拣货员经常误触回到桌面,连接就断了。我们的做法是,在小程序内维护一个本地的扫码待发队列(利用微信的FileSystemManager写本地缓存文件,而不是放内存,防止崩溃丢失),同时WebSocket心跳设为15秒一次,并且绑定小程序的前后台切换事件,一旦onHide就标记待重连,onShow立刻重建链路。这样用户无感,扫完码哪怕瞬间断网,数据也躺在本地,等连上了自动补发。
另一个关键是协议必须瘦身。刚开始我们图省事用JSON传扫码结果,一个包裹码加上设备号、时间戳,怎么也得300字节。后来换成MessagePack,体积直接砍到120字节左右。别小看这几百字节,在仓库网络拥塞时,小包更容易突发发送成功。服务端我们架了EMQX作为MQTT Broker,手机端通过WebSocket走MQTT协议,主题按仓库编号分区。MQTT的QoS1保证消息至少到达一次,但扫码业务最怕重复,比如网络抖动导致客户端重发,服务端必须做幂等——我们用扫码记录的唯一UUID做Redis原子写入,存在就直接丢弃,避免同一箱货重复入库。
最能体现架构功力的,是边缘节点的下沉。那客户有三个大冷库,分布在郊区,公网到阿里云中心机房有时候晚高峰能晃悠到200ms。我们在每个园区机房塞了一台低功耗边缘服务器,运行轻量版消息网关。手机连的是园区内网WiFi(我们专门优化了AP点位,避免金属屏蔽),延时实测8-15毫秒。边缘节点收到扫码请求,先回确认给手机(让界面秒显),然后异步批量压缩上送中心云数据库。就算园区光纤被挖断,本地还能撑好几个小时脱机作业,数据不丢。
这个项目上线四个月,客户算过账:省下买PDA的钱够买几千箱冰淇淋了。技术侧数据更硬,单仓峰值每秒并发扫码180次,端到端平均通信延时压到了90毫秒以内,错误率低于十万分之一。拣货员原先骂骂咧咧,现在干活利索多了。
做冷链系统的架构师,得懂制冷工艺,也得懂射频传播,更得懂怎么在破手机上写出稳如老狗的代码。我们团队这几年专攻这种消费级设备替代工业终端的活儿,踩过的雷比很多公司写的文档都多。如果你也在琢磨用手机小程序改造仓库扫码流程,上面这套低延时通信方案,或许能给你省下不少排查时间。
微信号:18581869297