1. 为什么我要写这篇“劝退文”
三年前,我负责给一个中型制造车间做设备联网改造。当时团队里几乎所有人都觉得MQTT是天然选择——轻量、省带宽、支持发布订阅、社区生态成熟,怎么看都是工业物联网通信协议的最优解。我们花了大概两个月把产线上的PLC、传感器、扫码枪、AGV调度终端全部接入了MQTT Broker,跑起来确实顺畅,数据延迟低,云端看板刷新也及时。
但三年下来,我踩的坑比预想的多得多。不是MQTT不好,而是它在某些工业场景下,真的不适合。这篇文章不是MQTT的入门教程,也不是协议对比科普,而是我在实际项目里用真金白银的调试时间和半夜被叫醒的代价换来的四个“不适合”场景。如果你正在做工业现场的设备联网、数据采集或边缘计算项目,正在纠结要不要上MQTT,那这篇内容能帮你省下至少三个月的试错成本。
我会把每个“不适合”场景讲清楚:为什么当时觉得适合、实际跑起来出了什么问题、背后的技术原因是什么、后来我们换成了什么方案、以及如果你非要在这个场景用MQTT,有没有折中办法。全文基于真实项目经验,但所有具体企业名称、设备型号、人员信息我都会做模糊化处理,只保留技术逻辑和实操细节。
2. 先搞清楚MQTT在工业现场到底扮演什么角色
2.1 MQTT的核心机制用大白话讲一遍
MQTT的本质是一个基于发布订阅模式的轻量级消息传输协议。你可以把它想象成一个邮局系统:所有设备把消息投递到邮局(Broker),邮局根据主题(Topic)把消息分发给订阅了该主题的接收者。发送方和接收方不需要知道对方的存在,只需要认识邮局就行。
这个模型在工业现场有三个天然优势。第一是解耦,设备之间不直接通信,新增或移除设备不影响其他节点。第二是省资源,协议头最小只有2字节,对于内存和算力有限的嵌入式设备很友好。第三是支持一对多,一个传感器数据可以同时被SCADA系统、云端看板、报警服务等多个消费者订阅。
但问题也恰恰藏在这些优势里。解耦意味着你无法直接知道消息有没有真正被处理,省资源意味着它牺牲了很多企业级消息系统才有的可靠性保证,一对多意味着消息可能被重复消费或丢失而难以追踪。
2.2 工业现场对通信协议的隐性要求
工业现场和消费级物联网最大的区别在于:消费级场景丢一条数据可能只是少记录一次温度,工业场景丢一条数据可能导致批次报废、设备损坏甚至安全事故。所以工业现场对通信协议有几个隐性但硬性的要求。
第一是确定性。消息从A到B的时间必须是可预测的,不能因为网络抖动或Broker负载高就出现几秒甚至几十秒的延迟。第二是可追溯。每一条控制指令和数据上报都必须有完整的日志链路,出了问题能倒查。第三是状态一致性。设备当前处于什么状态、指令是否执行成功,必须有明确的反馈机制,不能靠“发出去就不管了”。第四是断线恢复能力。工业现场网络闪断是常态,协议必须能处理断线期间的数据补传和状态同步。
MQTT在设计上更偏向“尽力而为”的轻量级消息传输,它把这四个要求中的大部分交给了应用层去实现。这就导致在很多工业场景下,你表面上用的是MQTT,实际上是在MQTT之上重新造了一套可靠消息系统的轮子。
2.3 我总结的四个“不适合”场景总览
下面这张表是我三年经验的浓缩,先给你一个全局视角,后面会逐个展开。
| 场景编号 | 场景名称 | 核心矛盾 | 典型表现 |
|---|---|---|---|
| 场景一 | 高频控制指令下发 | QoS机制无法保证指令时序和唯一执行 | 设备重复动作、指令乱序 |
| 场景二 | 大报文批量传输 | 协议设计偏向小消息,大包分片效率低 | 传输超时、内存溢出 |
| 场景三 | 强事务性数据同步 | 缺乏事务和确认机制,数据一致性难保证 | 数据对不上、对账困难 |
| 场景四 | 多级网络隔离环境 | 桥接模式在复杂网络拓扑下维护成本极高 | 消息环路、主题冲突 |
3. 场景一:高频控制指令下发——QoS救不了时序问题
3.1 当时为什么觉得MQTT适合
我们最开始把MQTT用在AGV调度指令下发上。调度系统计算出路径后,通过MQTT把转向、加速、减速、停靠等指令发给AGV车载终端。当时选MQTT的理由很充分:AGV数量多且位置不固定,发布订阅模式天然适合动态设备;指令数据量小,每条只有几十字节;QoS设为1就能保证至少送达一次。
刚上线的时候确实没问题,AGV数量少,指令频率低,跑了一周没出任何异常。但当我们把AGV数量从5台增加到20台,调度频率从每秒几次提升到每秒几十次之后,问题开始集中爆发。
3.2 实际跑起来出了什么问题
第一个问题是指令乱序。MQTT协议本身不保证消息顺序,虽然同一个Topic下同一个Client发送的消息在大多数Broker实现里是有序的,但一旦涉及多个发布者或者Broker做了集群,顺序就无法保证了。我们遇到过一次AGV先收到“加速”再收到“转向”的情况,结果AGV直接冲出了预定路径。
第二个问题是重复执行。QoS 1的语义是“至少送达一次”,这意味着接收方可能收到重复消息。AGV车载终端在弱网环境下经常收到重复的“停靠”指令,导致AGV在同一个位置反复启停。我们后来在应用层加了指令ID去重,但这就增加了终端算力消耗和状态管理复杂度。
第三个问题更隐蔽:指令确认和状态反馈不同步。调度系统发出“转向”指令后,AGV执行完成会发布一个“转向完成”状态。但这两个消息走的是不同Topic,调度系统可能先收到“转向完成”再收到自己发出的“转向”回显,导致状态机混乱。
3.3 背后的技术原因分析
MQTT的QoS机制本质上是在传输层做文章,它保证的是消息从发布者到Broker、从Broker到订阅者的传输可靠性,但它不保证消息的业务语义。QoS 1的“至少一次”意味着重复是允许的,QoS 2的“恰好一次”虽然理论上不重复,但实现代价高,而且在Broker集群模式下QoS 2的性能下降非常明显。
更关键的是,MQTT没有内置的时序保证机制。消息的先后顺序依赖于TCP连接的顺序,但一旦涉及多个TCP连接(比如多个发布者)或者Broker做了消息持久化和转发,顺序就无法保证了。工业控制指令对时序的要求是刚性的,A指令必须在B指令之前执行,这个要求MQTT满足不了。
还有一个容易被忽略的点:MQTT的Topic是单向的,指令下发和状态上报走的是不同Topic,这就导致指令和反馈之间缺乏天然的关联关系。你需要在应用层自己维护指令ID和状态映射,这本质上是在MQTT之上重建了一套请求响应模型。
3.4 后来我们换成了什么方案
对于高频控制指令场景,我们最终换成了基于TCP的自定义二进制协议。每条指令带唯一序列号,接收方必须按序列号顺序执行并返回确认,发送方收到确认后才发下一条。这套方案听起来很原始,但在工业控制场景下,简单可靠比优雅重要得多。
如果你非要用MQTT做控制指令,我有几个折中建议。第一,把所有控制指令收敛到一个发布者,避免多发布者导致的顺序问题。第二,在应用层实现指令序列号和去重逻辑,接收方维护一个最近处理过的指令ID窗口。第三,指令和状态反馈使用同一个Topic,通过消息类型字段区分,这样至少能保证同一个TCP连接内的顺序。第四,QoS设为1就够了,QoS 2在工业现场的性能损耗不值得。
注意:控制指令场景下,千万不要依赖MQTT的Retain消息来做状态同步。Retain消息只保留最后一条,如果设备在Retain消息更新间隙断线重连,会拿到过期的状态。
4. 场景二:大报文批量传输——小消息协议的大包困境
4.1 当时为什么觉得MQTT适合
我们有一个场景是每天凌晨把产线设备的日志文件上传到云端做分析。每个日志文件大概2到10MB,一天大概几百个文件。当时觉得MQTT既然能传传感器数据,传文件应该也没问题,而且MQTT over TLS还能省掉单独做加密的麻烦。
这个想法现在回头看非常天真。MQTT协议设计之初就是为小消息优化的,它的最大报文长度虽然理论上可以到256MB,但实际使用中超过一定大小就会出现各种问题。
4.2 实际跑起来出了什么问题
第一个问题是内存溢出。我们的边缘网关是ARM架构,内存只有512MB。当MQTT客户端尝试发送一个8MB的日志文件时,客户端库需要把整个文件加载到内存中再分片发送。如果同时有多个文件在传,内存直接爆掉,网关重启。
第二个问题是传输超时。MQTT的Keep Alive机制要求客户端在指定时间内必须发送PINGREQ,但如果客户端正在忙于发送大报文,可能无法及时发送心跳,导致Broker认为客户端离线,断开连接。我们遇到过好几次传了半小时的文件在最后几秒断线,前功尽弃。
第三个问题是Broker性能急剧下降。当多个大报文同时经过Broker时,Broker的内存和CPU使用率飙升,影响了同一Broker上其他小消息的传输延迟。一个日志上传任务把整个产线的实时数据看板卡死了,这是绝对不能接受的。
4.3 背后的技术原因分析
MQTT的报文结构决定了它不适合大报文。每个MQTT报文都有一个固定头部,包含报文类型和剩余长度字段。剩余长度字段采用变长编码,最多4字节,这意味着单个报文最大256MB。但问题不在于最大值,而在于传输效率。
当MQTT客户端发送大报文时,协议本身没有分片机制,分片是在TCP层做的。TCP分片对应用层透明,但MQTT客户端库通常需要把整个报文缓存在内存中,因为MQTT的报文长度字段在报文开头,接收方需要先读到长度才能知道要接收多少数据。这就导致发送方必须一次性准备好整个报文,接收方必须一次性接收完整个报文。
另外,MQTT的QoS机制在大报文场景下会带来额外的开销。QoS 1需要接收方返回PUBACK,如果报文很大,PUBACK的往返时间会很长,期间发送方可能重传,造成带宽浪费。
4.4 后来我们换成了什么方案
对于大文件传输,我们最终换成了HTTP分片上传。边缘网关把日志文件切成1MB的块,每块单独上传,云端接收后合并。HTTP的分块传输编码天然支持流式上传,不需要把整个文件加载到内存。而且HTTP的断点续传机制成熟,网络中断后可以从最后一个成功的分片继续。
如果你非要用MQTT传大报文,有几个缓解措施。第一,把大报文切成小块,每块用一个独立的MQTT消息发送,接收方根据消息中的序号重组。第二,调整Keep Alive时间,给大报文传输留出足够的心跳间隔。第三,使用单独的Broker实例处理大报文,避免影响实时消息。第四,考虑用MQTT over WebSocket,WebSocket的帧机制对大数据传输更友好。
但说实话,这些措施都是在跟协议的设计初衷对抗,维护成本很高。文件传输就用文件传输该用的协议,别硬塞给MQTT。
5. 场景三:强事务性数据同步——没有事务的消息系统
5.1 当时为什么觉得MQTT适合
我们有一个场景是MES系统和WMS系统之间的数据同步。MES完成生产工单后,需要把工单完成状态、物料消耗、成品入库等信息同步给WMS。当时觉得用MQTT做系统间解耦很合适,MES只管发消息,WMS只管收消息,两边不用直接调用接口。
这个场景的问题不是立即暴露的,而是在一次月末对账时才被发现。MES显示某工单已完成,WMS显示该工单的物料还没有扣减,两边数据对不上,差了十几条记录。
5.2 实际跑起来出了什么问题
第一个问题是消息丢失。虽然QoS设为2理论上不会丢消息,但在Broker磁盘满、网络分区、客户端异常退出等情况下,消息仍然可能丢失。而且QoS 2的“恰好一次”是在单个Broker内保证的,如果Broker做了集群或者桥接,跨Broker的消息传递无法保证恰好一次。
第二个问题是部分成功。一个工单完成事件实际上包含多个业务动作:更新工单状态、扣减物料库存、增加成品库存、记录操作日志。这些动作要么全部成功,要么全部失败。但MQTT消息是逐条发送的,如果第一条发送成功、第二条发送失败,就会导致数据不一致。
第三个问题是没有回滚机制。当WMS处理消息失败时,它只能记录错误日志,但无法通知MES回滚已经发送的消息。MES以为消息已经成功处理,实际上WMS那边已经失败了。
5.3 背后的技术原因分析
MQTT本质上是一个消息传输协议,不是事务处理系统。它没有分布式事务的概念,没有两阶段提交,没有回滚机制。QoS 2虽然听起来像“恰好一次”,但它保证的是消息传输层面的恰好一次,不是业务处理层面的恰好一次。
在事务性数据同步场景下,你需要的是ACID特性:原子性、一致性、隔离性、持久性。MQTT只提供了持久性的一部分(通过Broker的消息持久化),其他三个特性都需要应用层自己实现。
更麻烦的是,MQTT的消息确认机制和业务处理是分离的。接收方收到消息后返回PUBACK,这个PUBACK只表示消息收到了,不表示业务处理成功了。如果接收方在返回PUBACK之后业务处理失败,发送方完全不知道。
5.4 后来我们换成了什么方案
对于强事务性数据同步,我们最终换成了基于数据库事务的同步方案。MES和WMS共用一个数据库实例(或者用分布式事务框架),所有业务动作在一个数据库事务中完成,要么全部成功,要么全部回滚。这听起来很传统,但在数据一致性要求高的场景下,传统方案往往最可靠。
如果你非要用MQTT做事务性同步,有几个补偿措施。第一,在应用层实现事务日志表,发送方在发送消息前先记录事务日志,接收方处理成功后更新事务日志状态,定时任务扫描未完成的事务进行补偿。第二,使用消息去重表,接收方根据消息ID去重,避免重复处理。第三,实现业务层的回滚接口,当后续步骤失败时,调用前面的回滚接口撤销已完成的动作。
但这些措施本质上是在MQTT之上重建了一套事务系统,复杂度和维护成本都很高。如果数据一致性是硬需求,直接用支持事务的通信方式更省心。
实操心得:在工业现场,数据对不上是常态,但关键是要能快速定位是哪条消息、哪个环节出了问题。我们后来在所有MQTT消息里都加了traceId和业务流水号,配合日志系统,排查效率提升了很多。这个习惯建议你从一开始就养成。
6. 场景四:多级网络隔离环境——桥接模式的维护噩梦
6.1 当时为什么觉得MQTT适合
我们的工厂网络分为三层:设备层、车间层、厂级层。层与层之间有防火墙隔离,只开放特定端口。当时觉得MQTT的桥接模式很适合这种分层网络,每层部署一个Broker,层与层之间通过桥接同步消息,既满足了网络隔离要求,又实现了数据贯通。
这个架构在纸面上很漂亮,但实际维护起来简直是噩梦。
6.2 实际跑起来出了什么问题
第一个问题是消息环路。MQTT桥接默认会把本地Broker的消息转发到远程Broker,同时也会把远程Broker的消息转发到本地。如果配置不当,一条消息可能在两个Broker之间来回转发,形成环路。我们有一次因为桥接配置里没有正确设置Topic过滤,导致一条温度数据在两个Broker之间循环了上万次,把两个Broker都打挂了。
第二个问题是主题冲突。不同层级的Broker可能使用相同的Topic命名空间,桥接时如果不做Topic重映射,会导致消息覆盖或混淆。比如设备层有一个Topic叫/sensor/temp,车间层也有一个同名Topic,桥接后两个Topic的消息混在一起,无法区分来源。
第三个问题是故障排查困难。当消息从设备层经过车间层到达厂级层时,中间经过了两次桥接。如果消息丢失或延迟,你需要在三个Broker的日志里分别排查,而且每个Broker的日志格式和保留策略可能不同。我们有一次排查一条消息丢失,花了整整两天。
第四个问题是桥接的性能瓶颈。桥接本质上是一个MQTT客户端连接到远程Broker,它的吞吐量受限于单个TCP连接的性能。当消息量大的时候,桥接连接成为瓶颈,消息在桥接队列里堆积,延迟越来越大。
6.3 背后的技术原因分析
MQTT桥接的设计初衷是连接两个独立的MQTT网络,它假设两个网络之间的消息量不大,拓扑相对简单。但在工业现场的多级网络环境中,消息量大、Topic多、网络拓扑复杂,桥接模式的局限性就暴露出来了。
桥接模式的核心问题是它把网络拓扑的复杂性转嫁到了Broker配置上。每增加一层网络,就需要增加一层桥接配置,配置的复杂度呈指数增长。而且桥接配置是静态的,网络拓扑变化时需要手动调整所有相关Broker的配置,容易出错。
另外,MQTT桥接没有内置的环路检测机制。它依赖配置中的Topic过滤来避免环路,但Topic过滤是静态的,无法应对动态变化的Topic结构。一旦配置有误,环路就会发生,而且很难及时发现。
6.4 后来我们换成了什么方案
对于多级网络隔离环境,我们最终换成了消息队列网关方案。每层网络部署一个消息网关,网关负责协议转换和消息路由。设备层用MQTT,车间层用AMQP,厂级层用Kafka,网关负责在不同协议之间转换。这样每层网络可以使用最适合自己的协议,层与层之间的耦合度也降低了。
如果你非要用MQTT桥接,有几个必须做的配置。第一,在桥接配置中明确指定Topic过滤规则,只转发需要的Topic,避免全量转发。第二,为每个桥接连接设置唯一的Client ID和Topic前缀,避免冲突。第三,在桥接连接上启用QoS 1或2,确保消息不丢失。第四,部署监控系统,实时监控桥接连接的状态和消息堆积情况。第五,定期审查桥接配置,确保与当前网络拓扑一致。
但说实话,如果你的网络层级超过两层,或者消息量比较大,我建议直接考虑消息网关方案,别在MQTT桥接上死磕。
7. 四个场景的横向对比与选型建议
7.1 一张表看清四个场景的核心差异
| 对比维度 | 高频控制指令 | 大报文批量传输 | 强事务性数据同步 | 多级网络隔离 |
|---|---|---|---|---|
| 核心需求 | 时序保证、唯一执行 | 高吞吐、低内存 | 原子性、一致性 | 跨网络、可维护 |
| MQTT的短板 | 无时序保证、QoS重复 | 无分片、内存占用高 | 无事务、无回滚 | 桥接复杂、易环路 |
| 推荐替代方案 | TCP自定义协议 | HTTP分片上传 | 数据库事务 | 消息网关 |
| 折中方案复杂度 | 中 | 高 | 高 | 极高 |
| 是否建议硬用MQTT | 不建议 | 不建议 | 不建议 | 不建议 |
7.2 什么场景下MQTT仍然是好选择
说了这么多MQTT的不适合场景,但MQTT在工业现场仍然有大量适合的场景。比如设备状态上报,传感器数据采集,报警事件推送,这些场景的共同特点是:消息量小、频率适中、对时序要求不高、允许少量丢失。在这些场景下,MQTT的轻量、解耦、一对多优势能充分发挥。
我现在的项目里,MQTT仍然承担着大部分设备数据采集和状态上报的工作。关键是要认清它的边界,在适合的场景用适合的工具,而不是试图用一个协议解决所有问题。
7.3 选型时的五个自问自答
每次做通信协议选型时,我都会问自己五个问题。第一,消息丢了会怎样?如果丢了会导致严重后果,就需要可靠性保证更强的方案。第二,消息重复了会怎样?如果重复会导致业务异常,就需要去重机制或恰好一次语义。第三,消息顺序重要吗?如果顺序错了会导致问题,就需要时序保证。第四,消息量有多大?如果单条消息超过1MB或者频率超过每秒1000条,就需要考虑MQTT是否扛得住。第五,网络拓扑有多复杂?如果超过两层网络隔离,就需要考虑桥接或网关方案。
这五个问题的答案,基本能帮你判断MQTT是否适合当前场景。
8. 踩坑三年总结的实操避坑清单
8.1 配置层面的坑
第一个坑是Keep Alive设置太短。默认60秒在工业现场往往不够,网络抖动时客户端可能来不及发心跳就断线了。我一般设为120到300秒,具体看网络质量。
第二个坑是Clean Session没有正确使用。Clean Session设为true时,客户端断线后Broker会清除所有订阅和未确认消息。对于需要断线续传的场景,必须设为false,并且客户端要使用固定的Client ID。
第三个坑是Topic设计太随意。Topic是MQTT的核心概念,设计不好会导致订阅混乱和性能问题。我建议Topic层级不要超过5层,避免使用通配符订阅大量Topic,Topic名称要有明确的命名规范。
第四个坑是Broker没有做持久化。很多轻量级Broker默认不持久化消息,重启后消息全丢。工业现场必须开启持久化,并且定期备份。
8.2 运维层面的坑
第一个坑是没有监控。MQTT Broker的连接数、消息吞吐量、消息堆积量、客户端在线状态,这些指标必须实时监控。我们有一次Broker磁盘满了导致消息无法持久化,因为没有监控,过了三天才发现。
第二个坑是没有限流。工业现场的设备可能因为程序bug疯狂发送消息,把Broker打挂。必须在Broker层面做限流,限制单个客户端的发送速率和连接数。
第三个坑是没有日志。MQTT的调试日志在出问题时非常有用,但很多Broker默认不记录详细日志。建议开启消息级别的日志,保留至少7天。
第四个坑是没有灾备。单Broker部署在工业现场是危险的,Broker挂了整个数据链路就断了。建议至少部署两个Broker做集群,或者准备好快速切换方案。
8.3 开发层面的坑
第一个坑是客户端库选择不当。不同语言的MQTT客户端库质量参差不齐,有些库在断线重连、消息去重、内存管理方面有bug。建议选择社区活跃、经过生产验证的库。
第二个坑是没有处理断线重连。工业现场网络闪断是常态,客户端必须实现自动重连,并且重连后要重新订阅Topic、恢复未确认消息。
第三个坑是没有消息去重。QoS 1的重复消息是常态,接收方必须根据消息ID或业务流水号去重。
第四个坑是没有背压机制。当消息生产速度大于消费速度时,消息会在Broker或客户端堆积,最终导致内存溢出。必须实现背压机制,当堆积超过阈值时暂停生产或丢弃低优先级消息。
提示:工业现场的MQTT部署,建议把Broker放在边缘侧而不是云端。边缘Broker可以在网络中断时继续工作,保证本地设备之间的通信不中断。云端Broker只做数据汇聚和远程监控。
9. 如果重来一次,我会怎么设计这套系统
如果让我重新设计三年前的那套系统,我会做几个关键调整。
第一,把通信需求分层。控制指令走TCP自定义协议,保证时序和唯一执行。设备状态和传感器数据走MQTT,利用其轻量和解耦优势。文件传输走HTTP,利用其分片和断点续传能力。系统间事务性同步走数据库事务或消息队列的事务消息。
第二,在网络架构上,边缘侧部署轻量级Broker处理本地设备通信,云端部署集群Broker做数据汇聚。边缘和云端之间用消息网关而不是MQTT桥接,降低耦合度和维护成本。
第三,在应用层统一消息格式。不管底层用什么协议,消息体都使用统一的JSON或Protobuf格式,包含traceId、业务流水号、时间戳、消息类型等元数据。这样即使底层协议切换,上层业务逻辑不需要大改。
第四,从第一天就建立监控和告警体系。Broker状态、消息吞吐量、消息延迟、客户端在线率,这些指标必须实时可见。告警规则要覆盖磁盘、内存、连接数、消息堆积等关键维度。
第五,在项目初期就做压力测试。不要等到上线后才发现性能问题。用模拟工具模拟真实设备的消息量和频率,测试Broker和客户端的极限,提前发现瓶颈。
这套设计不一定完美,但至少能避免我踩过的大部分坑。通信协议选型没有银弹,关键是要认清每种协议的边界,在适合的场景用适合的工具。
10. 最后分享几个压箱底的小技巧
第一个技巧:用MQTT的Will消息做设备离线检测。设备连接时设置Will消息,当设备异常断线时,Broker会自动发布Will消息,其他系统可以据此判断设备离线。这比轮询设备状态高效得多。
第二个技巧:用共享订阅做负载均衡。MQTT 5.0支持共享订阅,多个消费者可以订阅同一个共享Topic,Broker会把消息轮流分发给消费者。这在需要多个消费者并行处理消息的场景下非常有用。
第三个技巧:用Topic别名减少报文大小。MQTT 5.0支持Topic别名,连接建立后可以用一个短别名代替长Topic名,减少每条消息的报文大小。对于Topic层级深、消息频率高的场景,能显著降低带宽消耗。
第四个技巧:用消息过期时间控制数据新鲜度。MQTT 5.0支持消息过期时间,Broker会在消息过期后丢弃它。对于实时性要求高的数据,设置合理的过期时间可以避免消费者处理过期数据。
第五个技巧:用请求响应模式做同步调用。MQTT 5.0支持响应主题和关联数据,可以实现请求响应模式。发送方在消息中指定响应主题,接收方处理完后把结果发到响应主题。这在需要同步获取结果的场景下很有用,但要注意设置合理的超时时间。
这些技巧都是我在实际项目中验证过的,但要注意MQTT 5.0的特性需要Broker和客户端库都支持。如果你的环境还在用MQTT 3.1.1,这些技巧可能用不了。升级到MQTT 5.0之前,先确认你的Broker和所有客户端库都兼容。
我在实际使用中发现,工业现场的通信协议选型,最怕的不是选错协议,而是选了一个协议之后就不敢换。技术方案应该随着业务需求的变化而演进,今天适合的方案明天可能就不适合了。保持开放的心态,多尝试不同的方案,才能找到最适合当前场景的那一个。