批量发货的启示
之前遇到过一个问题,批量发货一次性发货的订单数不能超过8000条。超过8000条,系统就会报错。采用的方法是异步推送发货数据到消息组件,后台任务脚本从消息组件解析发货数据,调用发货接口来完成发货操作。
8000条的订单发货数据大约是300KB左右,远远小于前端对文件的限制:1MB。 究竟是什么原因导致了这个限制呢?
起初,一直以为是前端或代理做了限制,然而通过在入口和关键位置打印相应消息,发现是一次性写入消息组件的内容超过长度限制导致消息组件报错了。
想到的第一个解决方案是: 以 N 条发货数据切分发货的订单数,分成若干组发送。尝试 N = 200,500,1000,2000, 3000, 4000,5000,6000, 发现情况时好时坏,有时可以成功,有时又会导致超时。不稳定。
于是,查看推送消息的接口代码,发现现有使用的方法是 push 单次推送,还有一个批量推送消息的 bulkPush 。咨询相关开发同学,了解这个在批量推送消息时性能更佳,能减少建立TCP连接的次数。于是尝试使用这个方法解决问题。发现速度确实更快了,可是接收端的数据内容有点怪异,似乎全部变成了单个数据,而不是之前的JSON结构的数据。敏感的我想到,很可能是数据结构的问题,需要将原来的数据作为列表的一个元素来传递。也就是说,之前使用 push 方法的参数是对象的列表,那么使用 bulkPush 的参数必须是对象的列表的列表,才能让接收端获得的是相同结构的JSON数据。
将 push(expressArray) 更改为 bulkPush([expressArray]) 后,问题解决,8000 条很快就发送出去了,并且接收端也正常解析到了相应数据。可支持到 20000条数据,差不多是 800KB 左右,接近前端的文件限制。
总结:
(1) 遇到任何问题,打断点或看日志,确定是入口之前的问题,还是程序中的问题;
(2) 批量传输数据,通常是要切分成多个批次传输的,避免一次性写入数据超过长度限制而报错;
(3) 批量传输数据,适宜采用批量接口,切忌单个循环传输数据;通常的模式是异步并发地传输;
(4) 若从原来的单个推送接口切换到批量推送接口,注意接收端的数据是否保持一致。