☰
MQTT在工业现场的4个“不适合”场景与选型建议
2026/10/14 16:10:19 网站建设 项目流程

MQTT在工业现场用了3年,我总结的4个“不适合”场景

1. 先说结论:MQTT在工业现场为什么会这么火,又为什么会被我拉进黑名单

三年前上一家单位做产线数采改造,我作为通信方案负责人,一头扎进MQTT的怀里。那时候理由很充分:协议轻、发布订阅解耦、能穿透车间到云端的复杂网络,一个Broker搞定所有转发。当时整个行业都在聊MQTT,似乎不用它就落伍了。三年下来,我在三条完全不同类型的产线上做过完整的MQTT落地,维护过上万台设备的数据链路,也确实靠着这套架构把设备OEE、能耗、节拍这些数据稳定送上了云端。但与此同时,我也实打实地在几个场景里被MQTT坑到半夜爬起来改程序。

先说MQTT为什么能在工厂里火起来。它本质上是基于TCP的发布订阅协议,消息由Broker中转,客户端只管发布和订阅,两边完全解耦。带宽占用小,一个报文头只有几字节,而且有QoS 0/1/2三个等级可以选,还支持遗嘱消息,设备异常掉线能立刻通知上层。再加上市面上有一大堆开源Broker,部署一个节点半小时搞定。对于“把设备数据搞到云端看板”这件事,MQTT确实是当前成本最低、见效最快的路子。

但我今天想聊的恰恰是它不适合的地方。工业现场和互联网环境最大的区别在于:确定性要求极高,断网不能停线,数据不能丢,时序不能乱,控制回路不能有几百毫秒的抖动。而MQTT在设计之初是为物联网遥测、移动推送这类弱实时场景准备的,它天然不具备强实时、强互操作、强自治这些工业现场的硬指标。下面这4个场景,是我在实际项目里验证过、踩过坑、最终不得不换方案的典型,希望能给正在做协议选型的人一点参考。

2. 不适合场景一:PLC之间高速实时联锁控制

2.1 现场情况:几十毫秒的联锁信号,MQTT根本递不到

有一次做一条半自动装配线的改造,线上有十几台设备,其中两台关键工位之间需要握手联锁:A工位完成压装动作后,必须在50毫秒内把“允许启动”信号给到B工位,否则B工位的伺服可能带着未退出的夹具启动,轻则撞机,重则伤到人。这套逻辑原本是继电器硬接线实现的,因为改造不想拉线,就有同事提议,反正我们已经上了MQTT,直接把联锁信号通过MQTT发过去不就行了。

当时我硬着头皮试了一下。PLC作为MQTT客户端,A设备发布一个“allowed_run”主题,B设备订阅这个主题。拓扑上看起来很简单,但实测下来,端到端延迟在80到450毫秒之间波动。这还只是单条消息、空载Broker的情况。为什么这么慢?因为整个链路要经历:A设备PLC扫描周期、TCP协议栈发送、Broker接收并匹配订阅、B设备TCP接收、B设备PLC扫描周期,再加上TCP本身的Nagle算法和ACK延迟合并,时延根本没法收敛。更不要说如果开了QoS 1,还有一轮确认握手。在联锁场景里,这个延迟根本不是“能不能优化”的问题,是机制上就赢不了。

2.2 为什么不适合:MQTT的先决条件就把实时控制排除在外了

说穿了,MQTT是“尽力而为”的异步通信,它没有一个全局时钟同步机制,也没有为确定性延迟做任何设计。Broker作为中心节点,所有消息都要经过它转发,一旦消息量变大或者Broker GC一抖,延迟马上变坏。而且工业控制需要的是“在一个确定的时间窗口内必须到达”的硬实时通信,这和MQTT的“什么时间到达不确定,但最终能到”完全不是一个维度。

我当时做了一个简单的对比测试,在同样两台PLC之间,用硬接线传输一个数字量信号,从输出到输入大概2毫秒;用Modbus TCP轮询,周期5毫秒能稳定读到;而MQTT单条消息的端到端时延均值虽然看着还行,但P99能达到几百毫秒,而且没有上界。对控制逻辑来说,没有上界就意味着不能用于安全联锁。

2.3 替代方案:该上总线就上总线,MQTT留给上面的监控层

如果要在设备之间做高速、确定性的信号交换,老老实实走工业现场总线:EtherCAT、PROFINET IRT、或者干脆硬接线。哪怕是普通Modbus TCP加上周期轮询,在大多数场景下也比MQTT靠谱。这些方案的共同点是支持等时同步、有确定的刷新周期,而且不需要中间Broker转发。

我最终在那个项目里保留了部分硬接线做安全联锁,另外用EtherCAT把两套PLC直接拉进同一个控制网络,动作时序精确到1毫秒以内。MQTT照样留着,但它往上走了一层,只负责把联锁动作的统计数据、工步时间、报警事件这些“事后数据”传到云端。这个分工直到产线搬迁都一直稳定运行。

提醒一句:千万别想着用MQTT做安全相关回路。哪怕你只打算把它当作“辅助信号”,也要问清楚:如果这条消息晚到500毫秒,现场的机械动作会不会出安全事故。会,就换方案。

3. 不适合场景二:海量高频振动数据的原始波形连续上云

3.1 现场情况:一台设备每秒几万点的波形,MQTT成了瓶颈

另一个让我深刻的场景是设备健康监测。当时给车间里一批旋转设备装振动传感器,采样率设到了25.6kHz,每个采样点16位,一块传感器每秒要产生约50KB的原始数据。一台设备按每次采集4096个点来算,一秒钟产生6到7个数据包,我试着把原始波形直接发布到MQTT的“vibration/raw”主题下,结果发现事情远没有那么简单。

车间里有80台设备,满负荷时每秒大约产生400到500条消息,每条消息1KB到4KB不等。这个消息量对MQTT来说其实不是毁灭性的,小规模测试时Broker也能撑住。但问题出在后续环节:接收端要把这些消息解析、排序、存储,还要做频谱分析。高频数据对时序极其敏感,MQTT的Topic多线程并发发布会导致消息到达顺序错乱,我得在消费端额外做时间戳排序和去重,这可比想象中麻烦得多。而一旦开启QoS 1保障不丢,每条消息确认带来的开销让吞吐直接掉了一半。

3.2 为什么不适合:MQTT擅长传“事件”,不擅长传“流数据”

MQTT本质上是离散消息模型,一条消息就是一个独立事件。但高频振动数据是连续采样得到的流数据,之间有时间连续性和强相关性,更适合用“批量文件传输”或“流式协议”来搬运。逐一打包成MQTT消息,每一个包都要承担协议开销、主题匹配开销、Broker转发开销、QoS确认开销,消息越大开销越大。到后期Broker的CPU持续满载,消费者处理不过来导致背压,消息积压越来越严重,最后又回到丢数据的老路上。

同时,高频原始数据对存储和网络带宽的消耗是惊人的:一台设备一天就能产生约4GB原始数据,80台设备就是320GB,就算云上能存,传输成本也不是产线能长期承担的。MQTT在这里只是“看似跑通了”,实际上把大量无效数据做低效搬运,整个链路的经济性非常差。

3.3 我的最终方案:边缘算好特征再上云,MQTT只做精简遥测

我花了两个月把这个坑填完,最终的架构是:传感器数据先进边缘网关,在网关里做FFT、时域特征提取,比如RMS、峰值因子、峭度、边带能量比,然后每15秒把这些特征值打包成一条MQTT消息发到云端。原始波形只保留在本地边缘存储,只有诊断程序判定异常时才把一段原始波形通过文件方式补传。

改造后,一台设备每15秒只发一条几百字节的消息,80台设备每15秒总计也就80条,消息量相比之前下降了三个数量级,Broker几乎没有任何压力。更重要的是云端拿到的数据是已经压缩过的特征,直接进SOR模型做趋势分析,省了一整套流处理集群。

我的经验是:数据量大的场景,先问一句“这些数据真的都要传吗”。MQTT适合传“从全量数据里提炼出来的结论”,不适合当全量数据的传送带。凡是每秒超过几十条、单条超过几十KB的连续数据,都要先做边缘压缩。

4. 不适合场景三:与既有PLC/DCS系统做深层次互操作

4.1 现场情况:车间里各种协议并存,MQTT只能当“翻译官”

工业现场最现实的问题就是存量设备太多。我们的车间里,既有某日系品牌的PLC走Modbus RTU,也有某欧美系PLC走PROFINET,还有几套老的DCS走OPC DA。它们之间本来就有控制系统层面的耦合,比如一条物流线要读取包装线的状态信号。我刚开始为了统一数据出口,想用MQTT作为“万能中间人”,让所有PLC都通过MQTT发布数据,再互相订阅,这样整个车间就变成了一个“统一消息总线”。

结果呢?协议转换的工作量完全失控。每台PLC的数据要映射成一个Topic,每个Topic下面再挂JSON、XML、二进制不同格式。而且不同品牌的PLC对数据类型定义、字节序、量纲、时区、时钟偏移都不一样,我要为每一对设备之间的关系单独写一套转换逻辑。最难受的是,现场的工程师拿着PLC程序问我“我这个DB块里的温度变量现在到底发到哪个Topic了”,我翻着Excel映射表,半天答不上来。

4.2 为什么不适合:MQTT只有传输通道,没有语义模型

MQTT协议本身对消息内容完全不设限,它不关心你发的是温度、压力还是布尔量。这对轻量接入是好事,但对工业互操作来说就是灾难。工业设备之间通信不只是“把字节送过去”,还要让对方理解“这个字节代表什么含义、单位是什么、质量戳是什么”。OPC UA之所以能在工业界立足,一个重要原因就是它定义了信息模型,服务器的地址空间里不仅有数值,还有元数据、单位、状态、历史趋势。而MQTT只负责“把消息从A送到B”,语义全靠两端各自约定。

业界有Sparkplug规范,试图在MQTT之上补一个统一数据模型,让设备状态、生老病死事件都有一套标准Topic结构和二进制负载格式。我在某个试点项目里试过Sparkplug,它确实能解决一部分“Topic乱、负载格式乱”的问题,但也引入了额外的复杂度,而且第三方设备、SCADA系统对Sparkplug的支持参差不齐,想靠它打通从PLC到PLC的深层次互操作,仍然很吃力。

4.3 我的经验:MQTT适合做“车间到云”的纵向传输,不适合做“设备到设备”的横向互操作

现在我在设计任何系统时都会把通信分成两层:底层设备之间直接用它们原生支持的工业协议,比如Modbus TCP、PROFINET、EtherNet/IP,必要时用OPC UA统一设备层的数据服务。MQTT只负责“南北向”,也就是边缘网关从OPC UA服务器读取设备数据后,统一转换成MQTT消息发给云端。这样,MQTT的Topic复用、负载格式、QoS策略只需定义一次,工程量大为简化。

那台车间改造项目后来把横向互操作的中间人角色换成了OPC UA,效果立竿见影:PLC和PLC之间直接通过OPC UA的服务器/客户端机制读写节点,所有数据类型和单位在地址空间里一查就知道,不再需要我的Excel映射表。MQTT还是没有拆,但它的角色变成了“OPC UA的数据出口之一”,工作稳定得多。

结论很明确:如果你要接的设备全是工业现场总线设备,别指望MQTT能替代它们之间的通信协议。正确的做法是“让总线的归总线,让MQTT的归MQTT”。

5. 不适合场景四:断网、弱网、移动环境下的高可靠自治系统

5.1 现场情况:网络一断,MQTT设备集体“失忆”

第三个让我彻底改变看法的场景,是在一个偏远站场的孤岛设备上。站场有十几台泵和阀门,通过4G和光纤混合网络接入总部物联网平台,我们部署了MQTT网关。平时一切正常,但一到雷雨季节、光纤被施工挖断、或者4G信号起伏大的时候,网关就会长时间离线。更麻烦的是,这些设备本身承担着就地自动控制的任务:液位高了要自动启泵、压力超了要自动放空,这些逻辑都在PLC里,不依赖云端,倒是没问题。

问题出在数据侧。网络恢复后,MQTT客户端重新连接Broker,最多只能拿到离线期间Broker暂存的消息。如果Broker的队列没配好,或者客户端断了太久,离线消息直接被清空,中间十几天的生产数据就永久消失了。我们还遇到过更诡异的情况:网络劣化导致TCP连接半开,客户端以为连着,Broker那边已经判定超时,消息就在半空中丢了,而MQTT的QoS只能保证“通道不丢”,无法保证“业务不丢”。

5.2 为什么不适合:中心化Broker是单点,离线即失联

MQTT的架构决定了它绕不开一个中心节点:Broker。客户端之间不直接通信,所有消息都要经过Broker。Broker在,数据传输畅通;Broker不在,哪怕两台设备就在同一个机柜里,也互相发不了消息。这在互联网场景下问题不大,因为云端的Broker通常有很高的可用性;但在工厂、矿山、野外站场,本地网络基础设施并没有那么可靠,断网是常态而不是异常。

而且MQTT设计时假设“客户端大多数时候在线,偶尔断线重连”,所以遗嘱消息、离线缓存这些机制都是围绕“重连后恢复”设计的,而不是围绕“长期离线还要继续自治运行”设计的。一旦客户端离线时间超出Broker的缓存窗口,离线期间的数据就没法补了。对生产系统来说,这等于失去了完整的追溯能力。

5.3 替代方案:边缘自治加数据补传,MQTT退居“云边通道”

我最终在那些孤岛设备上做了三件事:第一,每台设备本地加了一个小型边缘计算网关,所有自动化控制逻辑继续由PLC独立运行,数据采集、报警判定、历史存储全部在网关本地完成;第二,本地用一套嵌入式消息队列做设备间的短距离通信,保证生产数据不因为网络断开而缺档;第三,网关和云端之间的MQTT链路保持长连接,恢复后网关自动把离线期间积压的数据按时间顺序回放补传。

这套架构跑下来最明显的改善是:断网时间从几小时到几天,数据完整率都能保持在99.99%以上,不再出现“断一次网丢一截历史”的窘境。MQTT在这里依然有价值,因为它足够轻、重连机制成熟,适合作为远程数据传输的末端协议,但它再也不是那套系统中的“唯一真相”了。

给做选型的朋友一句忠告:无论你用MQTT还是别的协议,先模拟一次48小时断网。如果断网期产生的数据在恢复后无法自动补齐,你就该重新审视这套架构的可靠性了。

6. 三年的选型心得:MQTT的合适位置到底在哪里

如果只看前面的4个场景,你可能会觉得我在劝退MQTT。其实不是。我的态度一直是:MQTT是一个非常好的“边缘到云端”传输协议,它的生态、易用性和跨平台能力无可替代。在产线上,我依然大量使用MQTT来传设备状态、产量计数、能耗统计、报警事件、算法结果这些数据。它解决了我过去用私有TCP协议对接云端平台的种种痛苦,这是实实在在的价值。

我建议从下面这张表来帮助判断,什么时候放心用MQTT,什么时候果断绕开。

场景类型是否适合MQTT原因
设备状态遥测、产量统计非常适合消息频率低、数据量小、允许少量延迟
云端命令下发适合通过遗嘱消息和QoS 1可感知连接状态
边缘网关向云平台上报特征值很适合消息频率可控,主题结构清晰
海量高频原始波形传输不适合数据量大、时序敏感、开销高
设备间安全联锁控制坚决不适合时延无上界,无法保证确定性
PLC/DCS深度互操作不适合缺乏统一语义模型,工程复杂度高
断网自治区域的核心通信不适合中心化Broker导致离线即失联

我在实际项目里形成的固定套路是这样的:设备层用PLC原生的总线和OPC UA完成控制与数据交换,边缘层用MQTT做南北向传输,到云端后再落进时序数据库和消息队列。说白了,MQTT负责“把有用的数据从车间送出去”,不负责“车间内部的关键协同”。

三年下来,我最大的体会不是“MQTT不好”,而是“任何协议都有边界”。过去我容易迷信一个工具能打天下,出了问题时第一个反应是调参数、加超时、改重试,而不是停下来想一下是不是从一开始就选错了通信方式。做工业通信选型,最该问的问题其实不是“这个协议能不能连上”,而是三个问题:断网了怎么办、消息晚到了会怎样、设备A的消息设备B真的看懂了吗。这三个问题问完,MQTT该不该用、用在哪一层,基本就清楚了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询