You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MQTT 3.1.1 Clean Session连接断开后行为不符合预期

问题分析与解决方案

核心问题:测试场景不符合预期

你在测试中错误断开了发布者机器的以太网,但订阅者与Broker在同一机器,通过本地回环接口(127.0.0.1)通信,物理以太网断开不会影响本地连接——订阅者始终与Broker保持在线状态。因此发布者重连后发送的缓存消息会被Broker直接转发给订阅者,这与clean session特性无关。

原因拆解

  1. 本地回环不受以太网断开影响:订阅者与Broker的连接基于127.0.0.1,属于本地通信,断开物理以太网不会中断该连接,Broker始终判定订阅者在线。
  2. TCP缓存机制:发布者断连时发送的QoS0消息会被操作系统TCP栈缓存,待网络恢复后,TCP会自动将缓存消息发送给Broker。
  3. clean session的作用边界:clean session仅在订阅者真正断开与Broker的连接且会话超时后生效——Broker会清除该订阅者的会话状态(包括订阅关系),此时收到的消息会被丢弃。但你的测试中订阅者从未断开,clean session未触发作用。

正确测试方法与解决方案

1. 模拟订阅者与Broker的真实断开

要验证clean session的效果,需让订阅者主动断开与Broker的连接,例如:

  • 直接停止mosquitto_sub进程;
  • 使用工具阻断本地连接,如执行tcpkill -i lo port 1883(需安装tcpkill);
  • 临时禁用回环接口(谨慎操作:执行sudo ifconfig lo down,测试后恢复sudo ifconfig lo up)。

2. 配置短Keepalive加速断开检测

为让Broker快速识别订阅者离线,给订阅者设置短Keepalive时间:

mosquitto_sub -q 0 -t test -k 5

Broker会在1.5倍Keepalive时间(即7.5秒)后判定订阅者离线,清除其会话(因clean session=true)。此时发布者发送的消息会被Broker直接丢弃,订阅者重连后不会收到断开期间的消息。

3. 理解QoS与消息流转逻辑

  • QoS0消息是“至多一次”,发布者不等待Broker确认,TCP会负责缓存重传;若需避免断连时的消息缓存,需发布者主动检测网络状态(如通过Keepalive)并停止发送。
  • 若使用QoS1/2,Broker会缓存消息直到订阅者上线,但clean session=true时,订阅者断开后Broker会清除会话,缓存的消息也会被丢弃。

原始测试信息

测试步骤

  • 收发机器通过以太网连接,模拟断连场景
  • 接收端启动Mosquitto:mosquitto -v -c /etc/mosquitto/mosquitto.conf
  • 接收端启动mosquitto_sub:mosquitto_sub -q 0 -t test
  • 发送端启动终端模式的mosquitto_pub:mosquitto_pub -q 0 -t test -d -h <ipAddress> -l
  • 发送3条消息,订阅者正常接收
  • 手动断开以太网电缆
  • 再发送3条消息,订阅者未接收
  • 重新连接电缆,预期订阅者不会收到最后3条消息,但实际仍收到。

补充信息

  • 订阅者和发布者均使用QoS 0,尝试强制消息不保留,QoS1/2组合测试结果一致
  • 根据Mosquitto文档,broker、发布者、订阅者默认启用clean session,无显式设置选项,仅可通过持久化标志禁用
  • 曾尝试为接收端设置短keepalive(1s),但mosquitto_pub的-l和-k参数无法同时使用

日志

mosquitto_pub日志

Client mosq-q9b2Lbd1tARoQKJssX sending CONNECT
Client mosq-q9b2Lbd1tARoQKJssX received CONNACK (0)
one
Client mosq-q9b2Lbd1tARoQKJssX sending PUBLISH (d0, q0, r0, m1, 'test', ... (3 bytes))
two
Client mosq-q9b2Lbd1tARoQKJssX sending PUBLISH (d0, q0, r0, m2, 'test', ... (3 bytes))
three
Client mosq-q9b2Lbd1tARoQKJssX sending PUBLISH (d0, q0, r0, m3, 'test', ... (5 bytes))
#此处断开电缆并发送最后3条消息
4
Client mosq-q9b2Lbd1tARoQKJssX sending PUBLISH (d0, q0, r0, m4, 'test', ... (1 bytes))
five
Client mosq-q9b2Lbd1tARoQKJssX sending PUBLISH (d0, q0, r0, m5, 'test', ... (4 bytes))
six
Client mosq-q9b2Lbd1tARoQKJssX sending PUBLISH (d0, q0, r0, m6, 'test', ... (3 bytes))

mosquitto日志

1719010537: mosquitto version 1.4.15 (build date Tue, 18 Jun 2019 11:42:22 -0300) starting
1719010537: Config loaded from /etc/mosquitto/mosquitto.conf.
1719010537: Opening websockets listen socket on port 9001.
1719010537: Opening ipv4 listen socket on port 1883.
1719010537: Opening ipv6 listen socket on port 1883.
1719010537: New connection from <receiver> on port 1883.
1719010537: New client connected from <receiver> as mosq-Wze2t5NWmKTwMdQOzi (c1, k60).
1719010537: Sending CONNACK to mosq-Wze2t5NWmKTwMdQOzi (0, 0)
1719010573: Socket error on client mosq-Wze2t5NWmKTwMdQOzi, disconnecting.
1719010587: New connection from <sender> on port 1883.
1719010587: New client connected from <sender> as mosq-q9b2Lbd1tARoQKJssX (c1, k60).
1719010587: Sending CONNACK to mosq-q9b2Lbd1tARoQKJssX (0, 0)
1719010595: New connection from 127.0.0.1 on port 1883.
1719010595: New client connected from 127.0.0.1 as mosqsub|30731-MichaelJe (c1, k60).
1719010595: Sending CONNACK to mosqsub|30731-MichaelJe (0, 0)
1719010595: Received SUBSCRIBE from mosqsub|30731-MichaelJe
1719010595:     test (QoS 0)
1719010595: mosqsub|30731-MichaelJe 0 test
1719010595: Sending SUBACK to mosqsub|30731-MichaelJe
#前3条消息:
1719010599: Received PUBLISH from mosq-q9b2Lbd1tARoQKJssX (d0, q0, r0, m0, 'test', ... (3 bytes))
1719010599: Sending PUBLISH to mosqsub|30731-MichaelJe (d0, q0, r0, m0, 'test', ... (3 bytes))
1719010601: Received PUBLISH from mosq-q9b2Lbd1tARoQKJssX (d0, q0, r0, m0, 'test', ... (3 bytes))
1719010601: Sending PUBLISH to mosqsub|30731-MichaelJe (d0, q0, r0, m0, 'test', ... (3 bytes))
1719010602: Received PUBLISH from mosq-q9b2Lbd1tARoQKJssX (d0, q0, r0, m0, 'test', ... (5 bytes))
1719010602: Sending PUBLISH to mosqsub|30731-MichaelJe (d0, q0, r0, m0, 'test', ... (5 bytes))

#此处断开电缆
#无操作
#重连后

1719010634: Received PUBLISH from mosq-q9b2Lbd1tARoQKJssX (d0, q0, r0, m0, 'test', ... (1 bytes))
1719010634: Sending PUBLISH to mosqsub|30731-MichaelJe (d0, q0, r0, m0, 'test', ... (1 bytes))
1719010634: Received PUBLISH from mosq-q9b2Lbd1tARoQKJssX (d0, q0, r0, m0, 'test', ... (4 bytes))
1719010634: Sending PUBLISH to mosqsub|30731-MichaelJe (d0, q0, r0, m0, 'test', ... (4 bytes))
1719010634: Received PUBLISH from mosq-q9b2Lbd1tARoQKJssX (d0, q0, r0, m0, 'test', ... (3 bytes))
1719010634: Sending PUBLISH to mosqsub|30731-MichaelJe (d0, q0, r0, m0, 'test', ... (3 bytes))

mosquitto_sub日志

one
two
three
#此处断开电缆
#无操作
#重连后
4
five
six

内容的提问来源于stack exchange,提问作者Barsaas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 05:19:51