MQTT实战 - 生产环境MQTT丢包终极排查,8年经验总结
01、开篇:一次"丢包"引发的凌晨 3 点告警
那是去年冬天,凌晨 2:47,告警群炸了。
客户投诉:2000 台设备在线,每天稳定丢 0.3% 的告警消息。 0.3% 这个数字很微妙——太小不触发系统告警,太大用户直接打电话骂人,0.3% 刚好让你查了 3 天才发现。
第一天,设备组说"我发了,PublishAsync 没抛异常";第二天,平台组说"我没收到,订阅回调没触发";第三天,我去翻 EMQX 日志,发现大量 publish denied——根因是 ACL 规则顺序错误:先 deny 了 device/# 通配符,后 allow 了 device/001/alarm 具体 topic,Broker 按规则顺序匹配,直接静默丢弃。
没人看 publish denied 日志,因为默认日志级别是 INFO,而我们的采集阈值设的是 WARNING。
三天,一个 ACL 顺序问题,0.3% 的告警丢失,凌晨 3 点的告警。
这件事让我明白两件事:
-
MQTT 丢包排查不能靠猜,需要系统化的分层框架。
-
MQTT 从不主动告诉你它丢了消息——它只会安静地帮你把这条消息"当成已经处理完了"。
下面这套东西,是我 8 年踩坑后沉淀下来的:一个五层模型、六种丢包场景、一套三段定位法、一份自检清单。照着走,95% 的丢包能在 1 小时内定位到层。
02、先立一个认知——MQTT 里没有"端到端可靠"
很多人以为"我设了 QoS 2,消息就万无一失"。这是生产环境丢包事故的头号认知源头。
MQTT 的 QoS 只保证一件事:报文在「客户端 ↔ Broker」这一跳链路上的传递语义(1 次 / 2 次 / 4 次握手)。它不管:
-
消息有没有被 Broker 主动丢弃(队列满、包过大、ACL 拒绝、磁盘满);
-
订阅端收到之后有没有正确处理(异常、超时、反序列化失败、业务幂等误吞);
-
消息有没有真的到达正确的 Topic(通配符不匹配 = 静默丢弃,协议不报错)。
可靠性 = 合适的 QoS + 端到端 QoS 对齐 + 业务层幂等 + 端到端对账。
缺最后一项,你永远无法证明"没丢",只能靠客户投诉来发现。
- 点赞
- 收藏
- 关注作者
评论(0)