前两年接手一个工业现场的数据采集项目,大概三百多个节点,走的是共享广播型总线。调试阶段单节点通信完全正常,一旦挂载超过六十个节点,系统就开始出现规律性抽风:每间隔几秒到十几秒,所有节点的上报数据集体延迟,延迟时间从正常的一百多毫秒飙到两三秒,然后突然恢复正常,再抽风,周而复始。现场工程师换了三批终端设备,重写了两次上位机轮询逻辑,甚至把总线电缆从头到尾重新敷设了一遍,问题照旧。我过去之后,先没碰设备,而是拿了一个带时间戳的总线监听工具抓了半小时的数据,看完之后发现一个很反直觉的现象:总线上数据帧的总量并不大,带宽占用率不到百分之十五,但某些时间窗口内,广播类报文会连续出现,把数据信道整段整段地堵死。那次排查花了整整两天,最后定位到的根因和很多人第一反应的方向完全不一样。这件事让我意识到,广播信道和数据信道混在一起跑的系统,出问题的时候,带宽占用率这个指标会骗人。
先搞清楚广播和数据到底抢的是什么
很多工程师一听到阻塞,第一反应是带宽不够,于是去算波特率、算报文长度、算每秒帧数。这个思路在纯点对点或者纯轮询系统里是对的,但在广播和数据混跑的总线上,带宽只是表层。真正的矛盾在于仲裁机制和信道占用权的分配方式。
广播报文通常有一个特点:它不针对某个特定接收者,所以发送方在发送之前往往不会去确认信道是否空闲,或者即使确认了,也因为广播的优先级设定得比较高,导致它在仲裁中总是赢。而数据报文一般是定向的,发送方会等一个应答或者确认,一旦广播把信道占住,数据报文就只能退避重试。退避重试本身又会产生额外的仲裁开销,进一步挤压有效数据窗口。
这里有一个隐形陷阱:广播报文的发送周期如果是固定定时触发的,那么当节点数量增加时,多个节点的广播定时器会逐渐漂移,最终在某些时间点上叠加在一起。叠加的