尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
自动售货机MQTT通信踩坑实录:从掉线丢消息到百万级设备稳定在线的进化之路~YH
MQTT是物联网的事实标准自动售货机也不例外。但把MQTT跑稳尤其是在工业环境下跑稳比想象中难得多。一、协议选型为什么是MQTT不是HTTP做设备通信方案设计的时候第一个问题就是用HTTP还是MQTTHTTP的优点是简单谁都会用。缺点也很明显轮询效率低、实时性差、服务器压力大。每台设备每隔几秒就轮询一次一万台设备就是每秒几千次请求服务器扛不住。MQTT的优势长连接、实时推送、协议轻量、支持大规模并发。一台MQTT服务器可以扛几万到几十万台设备。消息是实时推送的不需要轮询。所以在售货机场景下MQTT是唯一合理的选择。二、QoS级别怎么选这是一个哲学问题MQTT有三个QoS级别。我们花了两周时间在这上面纠结。QoS 0最多分发一次。消息可能丢但开销最小。QoS 1至少分发一次。消息不丢但可能重复。QoS 2正好一次。消息不丢不重复但开销最大。我们的选择大部分消息用QoS 1支付相关用QoS 2心跳用QoS 0。开门指令、支付结果这类消息不能丢用QoS 1确保送达。重复消费虽然麻烦但可以幂等处理。心跳丢了无所谓下一个心跳周期会补上。支付相关的关键指令用QoS 2——虽然开销大但出错代价更高。坑点提醒QoS 2在大规模场景下性能下降明显。如果设备数量超过5万台QoS 2的吞吐量可能成为瓶颈。此时需要在QoS 1 应用层去重和QoS 2之间做权衡。三、心跳间隔设多少30秒是经验值心跳太频繁服务器压力大设备耗电。心跳间隔太长断线检测不及时。我们经过压测得出的结论心跳间隔30秒是最优值。设备每30秒发一次PINGREQ。服务器在1.5倍心跳间隔45秒内没收到心跳判定设备离线。但不断开连接再等1.5倍间隔90秒还没收到彻底断开并触发遗嘱消息。实测数据30秒心跳间隔下单台服务器能稳定支撑2.8万到3.2万台设备。超出这个数量需要做集群。四、遗嘱消息设备死了要让服务器知道这是MQTT最被低估的功能但在售货机场景里超级有用。设备连接时设置遗嘱消息Last Will——如果我异常断线了把这个消息发到指定Topic。服务器收到后可以立即知道哪台设备离线了触发告警。我们利用遗嘱消息实现了设备异常离线告警——运维团队会在5秒内收到钉钉通知比用户发现机器黑屏快了至少10分钟。五、消息持久化断网期间的消息不能丢这是生产环境最大的坑。设备断网期间云端下发的指令改价、调温、远程开门如果设备收不到会造成很严重的问题。我们的方案云端消息下发时先存入数据库状态标记为未送达。设备上线后云端检查所有未送达消息批量推送给设备。设备端收到消息后回复ACK确认。云端收到ACK后将消息状态更新为已送达。消息有效期超过24小时未送达的消息自动失效运维人员会收到通知手动处理。这个机制保证了一台设备断网一周后重新上线期间的所有指令都能被正确执行。六、Topic设计分得越细越好Topic设计决定了消息路由的灵活性和系统扩展性。我们的Topic分层vending/{deviceId}/state/online - 设备上线通知vending/{deviceId}/state/heartbeat - 设备心跳vending/{deviceId}/command/price/update - 云端下发改价指令vending/{deviceId}/command/temperature/set - 云端下发调温指令vending/{deviceId}/event/order/paid - 设备上报支付成功vending/{deviceId}/event/error - 设备上报故障这种设计的好处运维人员可以订阅特定设备的特定事件数据分析系统可以只订阅event/order相关Topic云端可以批量下发指令。七、性能压测数据这是我们压测的最终数据供参考指标数值单服务器最大设备连接数3.2万台消息吞吐量QoS 18600条/秒消息吞吐量QoS 22100条/秒平均消息延迟120ms99.9%消息延迟380ms系统可用性99.97%八、总结MQTT看起来很轻量但要把生产环境的稳定性做好需要从QoS、心跳、遗嘱、持久化、Topic设计等多个维度去优化。最核心的一条经验MQTT不是搭起来就能用的基础设施它需要根据业务场景做大量配置和二次开发才能支撑百万级设备的稳定在线。
RELATED

相关推荐

LangChain组件拆解:从一次聊天调用理解AI应用组合艺术

LangChain组件拆解:从一次聊天调用理解AI应用组合艺术

1. 项目概述:一次聊天调用背后的LangChain世界 如果你刚开始接触LangChain,面对官方文档里琳琅满目的“组件”(Component)和“链”(Chain)概念,可能会感到一阵眩晕。我们总听说LangChain的核心思…

📅 2026/9/8 16:03:17
AI矩阵获客实战案例大揭秘!

AI矩阵获客实战案例大揭秘!

AI矩阵获客实战案例大揭秘!在当今数字化商业浪潮中,企业获客面临着诸多挑战,AI 矩阵获客作为新兴解决方案应运而生。然而,这一领域在发展过程中也遭遇了不少核心技术挑战。当前,企业营销正面临“人力成本高、获客效率低…

📅 2026/8/27 21:54:03
3分钟搞定音乐加密文件!Unlock Music Electron桌面版终极指南

3分钟搞定音乐加密文件!Unlock Music Electron桌面版终极指南

3分钟搞定音乐加密文件!Unlock Music Electron桌面版终极指南 【免费下载链接】unlock-music-electron Unlock Music Project - Electron Edition 在Electron构建的桌面应用中解锁各种加密的音乐文件 项目地址: https://gitcode.com/gh_mirrors/un/unlock-music-e…

📅 2026/9/11 21:03:35
MORE NEWS

更多资讯

📰

从环境搭建到事务处理:Java+MySQL图书管理系统实战指南

简介:这是一份基于JAVA与MySQL的图书管理系统完整项目资源,面向计算机专业学生、课程设计及毕业设计者,也适合希望学习Java项目开发的初学者。系统采用MVC三层架构组织代码,实现了用户登录、用户信息管理、图书信息增删改查、图书…

📰

从源码构建ImGui.Net:C#环境下即时模式UI的完整实践指南

1. 项目概述:为什么要自己构建ImGui.Net先说结论:ImGui是图形调试和工具开发领域绕不开的一个库,而ImGui.Net是它在C#生态里的绑定层。我最早接触ImGui是在做图形引擎编辑器的时候,当时需要在运行时快速搭建一个属性面板&#xff…

📰

Learn-Claude-Code 笔记 | Concurrency | s08 Background Tasks 的 Base URL 改到 TaoToken 实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

9.9包月+OpenCode教程:开源编程神器接入TaoToken实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

UltraEdit 正则表达式实战:删除包含某个字符串的所有行(含 TaoToken 配置示例)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

deadline前两周,我靠这个工具把论文从大纲补到终稿

先交代背景:我是三月底才定题的,比同届同学晚了整整一个月。原因很丢人——前面换了两个方向,导师都没点头,最后这个题目是三月二十八号才通过开题的。距离五月底答辩,满打满算两个月,中间还要实习、跑数据…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬