将ROS发布者缓冲区设为1、订阅者缓冲区设为1000是否会丢失消息
ROS发布者与订阅者缓冲区机制问题解答
核心结论
这种配置下大概率会出现消息丢失,丢失会发生在发布者侧,和订阅者1000大小的缓冲区没有关系。
两类缓冲区的核心作用
首先明确ROS话题通信中两个缓冲区的定位,对应创建发布者、订阅者时传入的queue_size参数:
- 发布者缓冲区:是发布者节点本地维护的出站消息暂存队列,用来存放已经调用
publish()接口、但还没来得及通过传输层发送给所有订阅者的消息。队列满时默认采用「丢弃最早入队消息」的策略,新消息会直接入队覆盖旧消息。 - 订阅者缓冲区:是订阅者节点本地维护的入站消息暂存队列,用来存放已经从传输层接收到、但还没被回调函数处理的消息。队列满时同样默认丢弃最早入队的未处理消息。
为什么发布者缓冲区设为1会导致丢消息
发布者缓冲区的大小是消息传输链路的第一个瓶颈,哪怕订阅侧有再大的缓冲空间,只要发布侧的消息生产速度超过了传输层能发送的速度,就会直接在发布端丢消息,根本不会到达订阅者的缓冲区:
举个实际场景为例:假设发布者的消息发布频率是100Hz(每秒发100条),哪怕网络条件很好,TCP传输本身是可靠的,但如果订阅者的回调处理速度只有50Hz,会导致TCP窗口被占满,传输层无法及时发送新的消息,此时发布者本地只有1大小的队列会瞬间被占满,每生成一条新消息就会把还没发出去的旧消息直接丢弃,最终订阅者最多只能收到一半的消息。
只有当发布者的消息发布频率极低,每条新消息生成时,上一条消息已经完全发送给所有订阅者的场景下,才不会出现消息丢失,这种场景在实际生产中几乎不存在。
消息不丢失的两个必要前提
不管缓冲区怎么配置,只要满足以下两个条件就不会出现消息丢失,只要任意一个条件不满足都会出现对应位置的消息丢弃:
- 发布者的消息生产速度 ≤ 传输层将消息发送到订阅者的速度,此时发布者缓冲区不会堆积
- 订阅者的回调处理速度 ≥ 消息到达订阅者的速度,此时订阅者缓冲区不会堆积
内容的提问来源于stack exchange,提问作者sharath p baliga
相关产品推荐
相关产品推荐

