上周三凌晨两点,我被叫起来处理一个现场问题。设备在客户那里跑了三个月,突然开始随机掉线。不是全部掉,是每隔十几分钟就有一两个连接断开,重连之后过一阵又断。客户那边做的是数据采集,几十个传感器节点通过无线模块往网关传数据,网关再通过有线网络上传。掉线意味着数据丢包,产线那边直接报警停机。说实话,这种"跑了一段时间才出问题"的故障最让人头疼。刚上电就挂反而好查,最怕这种时好时坏、没有规律的现象。到了现场,我先看网关的日志。发现掉线的时候,无线模块那边报的是"资源分配失败"。这个报错很笼统,但至少给了方向——不是射频信号问题,是模块内部的资源管理出了问题。接着我让现场人员把连接数降下来,从四十多个降到二十个,跑了两个小时,一次都没掉。再往上加,加到三十个左右,开始偶尔出现。加到四十个,十几分钟必掉。很明显,问题跟并发连接数强相关。回到资源分配这个点上。这个无线模块内部有一张连接表,每个连接要占一个表项。表项本身不大,但每个表项关联的发送缓冲区、接收缓冲区、定时器、重传队列,这些加起来就很可观了。模块的总内存是固定的,连接数越多,每个连接能分到的资源就越少。这里有一个公开资料很少讲的隐形陷阱:很多模块的连接表项是静态分配的,也就是说,只要连接建立,不管这个连接当前有没有数据要发,它占用的缓冲区大小是固定的。你建了四十个连接,每个连接分到两KB发送缓冲,那就是八十KB。模块总共就一百多KB的RAM,剩下给协议栈、给中断处理、给其他任务的就不够了。不够了会怎样?不是立刻崩,而是进入一种"饥饿"状态。某个连接要发数据,发现缓冲区不够,就等。等的时候如果超时了,协议栈就认为这个连接出了问题,主动断开。断开之后,连接表项释放,缓冲区回收,其他连接又能正常一会儿。这就是为什么掉线是
阅读完成 · 觉得有帮助?