什么事情都没有做,为什么MQTT设备频繁收到相同消息
什么事情都没有做为什么MQTT设备频繁收到相同消息一、问题现象二、排查过程三、根因分析3.1 同主题 Retain true 导致死循环3.2 为什么指令类消息不能用 Retain四、Retain保留消息机制说明4.1 什么是 Retain4.2 Retain 使用策略五、修复建议5.1 主题分离5.2 Retain 配置调整5.3 配置检查项六、总结一、问题现象本人现在在做物联网智能设备开发周末休息的时候有客户使用产品反馈 4G 开关产品存在以下异常设备一直在循环上报两条完整消息Topic: /tianyi-up-smartswitch1-866597078379797 QoS: 0 { imei: 866597078379797, iccid: 89861125208093419149, online: 1, version: 1.0.10 } Topic: /tianyi-up-smartswitch1-866597078379797 QoS: 0 { success: true, message: ok, imei: 866597078379797, source: command, commandName: controller-restart, messageId: }上午下发软重启任务时retain 默认成 true客户当时未注意该配置后发现此问题二、排查过程经逐步排查从表象定位到根因排查步骤发现初步分析设备循环上报在线状态和重启响应消息重复收发深入排查发现发布主题与订阅主题使用同一主题/tianyi-up-smartswitch1-866597078379797进一步确认上午下发软重启指令时retain默认设为true根因定位设备收到指令后回包回包又被自己收到形成消息死循环三、根因分析3.1 同主题 Retain true 导致死循环客户平台 Broker 设备 │ │ │ │── retaintrue ──controller-restart────────→│ │ │ 发布到 /tianyi-up-smartswitch1-... │──→ 设备收到重启指令 │ │ │ 执行重启回包 │ │ │←──success:true...────────────│ │←────────────────────────────────────────────│ 发布到同一主题 │ │ │ │ │ 客户收到响应 │ │ │ 如果也做响应... │ │ │── 再次回包 ─────────────────────────────────→│ │ │ ↓ 无限循环 │ │核心问题发布和订阅使用同一主题/tianyi-up-smartswitch1-866597078379797指令下发时retain true回包也带retain true设备收到自己的回包误认为是新指令再次响应并上报3.2 为什么指令类消息不能用 Retain问题后果指令重复执行设备断网重连后再次执行旧指令如再次重启时序混乱新旧指令混在一起无法区分安全风险开/关等指令被保留意外触发后果严重消息循环同主题下回包触发自我响应无限循环上报四、Retain保留消息机制说明4.1 什么是 Retain当发布消息时设置retain trueBroker 会保存该主题的最后一条消息。之后任何新订阅者连接时会立即收到这条保留消息即使消息是在订阅之前发布的。4.2 Retain 使用策略消息类型Retain原因控制指令软重启、开/关、参数设置❌false只执行一次过期即失效设备响应/回包❌false避免循环触发设备状态在线/离线✅true新订阅者需要知道当前状态配置信息阈值、工作模式✅true设备上线立即获取最新配置遥测数据温度、电量❌false实时数据保留旧值无意义五、修复建议5.1 主题分离建议将收发分离为两个主题用途主题路径说明平台下发指令/tianyi-up-smartswitch1-{imei}/cmd平台发布设备订阅设备上报响应/tianyi-up-smartswitch1-{imei}/ack设备发布平台订阅平台下发指令 ──→ /tianyi-up-smartswitch1-866597078379797/cmd ──→ 设备订阅收到 设备回响应 ──→ /tianyi-up-smartswitch1-866597078379797/ack ──→ 平台订阅收到 ↑ 互不干扰无循环主题分离后即使同时订阅cmd和ack两个主题也不会产生循环。因为设备回包只发到ack不会发到cmd。5.2 Retain 配置调整消息类型Retain 设置建议平台下发指令软重启、开/关false发布时显式设置设备响应/回包false设备端已默认关键操作发布任何控制指令时显式设置retain false。5.3 配置检查项序号检查项优先级状态1下发指令时retain显式设为false 高☐2发布主题与订阅主题分离cmd / ack 高☐3消息增加唯一 IDmessageId支持业务层去重 低☐六、总结客户最初反馈设备一直循环上报两条数据经排查根因是上午下发软重启指令时retain默认成true且收发使用同一主题导致设备回包被自身再次接收形成消息死循环。建议通过主题分离及调整 retain 配置解决。