Mosquitto订阅因系统确认丢消息及Agent订阅异常问题咨询
首先,从你提供的日志和描述来看,存在两个核心问题:agentB客户端频繁重连并重复订阅,以及消息丢失。下面一步步拆解排查:
一、解决agentB频繁重连重复订阅的问题
从日志里反复出现的Client agentB sending CONNECT可以看出,agentB的客户端在不断断开并重新连接MQTT Broker,进而重复执行订阅操作。常见原因和解决方法如下:
检查Keepalive配置与心跳机制
MQTT的Keepalive机制会让Broker在指定时间内没收到客户端的心跳包(PINGREQ)就判定客户端离线,主动断开连接。你需要:- 确认agentB客户端的keepalive参数设置是否合理(建议设为60秒左右,不要过短)。
- 检查agentB代码是否在keepalive周期内正确发送心跳包,避免因为没有心跳导致Broker主动断开。
- 用
mosquitto -v启动Broker,查看详细日志,确认是否有Client agentB has exceeded timeout这类超时断开的记录,这能直接定位是心跳问题导致的重连。
排查网络稳定性
网络波动、丢包过高也会导致连接频繁断开。可以用ping或mtr工具测试agentB与Broker之间的网络连通性,看是否存在持续丢包或延迟过高的情况。如果是网络问题,需要先解决网络链路的稳定性。检查agentB的代码逻辑
很可能是agentB的客户端代码存在逻辑错误,比如:- 循环调用连接接口,导致重复发起连接请求;
- 连接回调处理不当,比如连接失败后没有设置合理的重连间隔,而是立即重试,造成频繁重连;
- 没有正确判断当前连接状态,在已连接的情况下再次发起连接。
调整Clean Session配置
如果agentB设置了clean session = true(默认值),每次重连都会创建新的会话,Broker不会保留之前的订阅信息,客户端必须重新订阅。如果需要持久化订阅,建议将clean session设为false,这样Broker会保留客户端的订阅会话,重连后不需要重复订阅(客户端仍可主动订阅以确保可靠性)。
二、解决消息丢失的问题
结合重连的情况,消息丢失通常和订阅配置、QoS设置、会话持久化有关,另外还有一个关键细节需要注意:
先确认订阅主题是否匹配
从你的日志可以看到:Topic: dispatcher/broadcast,但你说要订阅的是agentB/broadcast,而且agentA是向agentB/broadcast发布消息。这是明显的主题不匹配!agentB当前订阅的是dispatcher/broadcast,自然收不到agentB/broadcast的消息。如果你的mosquitto_sub订阅的是agentB/broadcast却收不到消息,需要先检查agentA是否成功发布了消息(可以用mosquitto_pub手动发送测试消息,看mosquitto_sub是否能收到)。合理设置QoS级别
MQTT的QoS决定了消息的可靠性:- QoS 0:最多一次,消息发送后不确认,Broker不会缓存,断开连接后消息会丢失;
- QoS 1:至少一次,Broker会缓存消息直到收到客户端的确认,重连后会重新发送;
- QoS 2:恰好一次,最高可靠性,确保消息只被送达一次。
如果需要避免消息丢失,建议发布时使用QoS 1或2,比如用命令:mosquitto_pub -t agentB/broadcast -m "test_message" -q 1,同时订阅端也设置对应的QoS级别。
启用会话持久化与Broker持久化
- 确保agentB的
clean session设为false,这样Broker会为客户端保留未送达的QoS 1/2消息,当客户端重连后继续推送; - 检查Mosquitto Broker的
persistence配置(默认开启),确保Broker将消息和会话信息持久化到磁盘,避免Broker重启后丢失消息。可以查看mosquitto.conf中的persistence true和persistence_location配置项。
- 确保agentB的
检查Broker权限配置
如果Broker开启了ACL(访问控制列表),需要确认agentA有发布agentB/broadcast主题的权限,agentB和mosquitto_sub有订阅该主题的权限。可以查看mosquitto.conf中的acl_file配置,检查对应的权限规则。
总结步骤
- 先修正agentB的订阅主题,确保和agentA发布的主题
agentB/broadcast一致; - 排查agentB频繁重连的原因(心跳、网络、代码逻辑);
- 调整QoS和clean session配置,启用持久化;
- 用
mosquitto -v查看Broker详细日志,追踪消息发布和订阅的全过程,定位问题。
内容的提问来源于stack exchange,提问作者hellojoshhhy

