2. MQTT协议核心概念
在农业物联网中,传感器节点往往部署在温室、大田、畜禽舍等分散位置,控制器和执行器又分布在另一侧,如果采用“点对点直连”的方式,每增加一个设备就要新增一条连接,系统很快会变得难以维护。MQTT 用一套轻量的发布/订阅机制解决了这个问题:设备不直接找对方,而是把消息交给 Broker(消息代理),由 Broker 按主题把消息分发给关心的订阅者。理解发布/订阅模型、主题与通配符、QoS、保留消息、会话与遗嘱消息这六个核心概念,是后续搭建农业数据通道和远程控制链路的基础。
发布/订阅模型:设备之间解耦
发布/订阅模型中有三类角色:发布者(Publisher)、订阅者(Subscriber)和代理(Broker)。以温室场景为例,土壤湿度传感器作为发布者,把测量值发布到主题 farm/greenhouse01/soil/moisture;灌溉控制器作为订阅者,提前向 Broker 订阅该主题;Broker 收到消息后,把消息转发给所有匹配的订阅者。发布者不需要知道谁在订阅,订阅者也不需要知道数据来自哪台设备,双方只通过主题这一“地址”建立联系。
这种解耦带来三个实际好处:一是新增一个手机端监控应用时,只需让它订阅相同主题,无需改动传感器固件;二是某个订阅者离线不会阻塞发布者,发布者照常上报;三是可以一对多分发,同一份湿度数据既能送给灌溉控制器,也能送给云端存储和报警服务。需要注意的是,MQTT 的发布/订阅是异步的,发布者发出消息后并不等待订阅者处理完成,因此对控制类指令要结合 QoS 和业务确认机制来保证可靠性。
主题与通配符:给农业数据编址
主题(Topic)是用斜杠分隔的层级字符串,类似文件路径,但不需要预先创建。建议按“场区/棚室/设备类型/测点”的层级设计,例如:
farm/greenhouse01/soil/moisture
farm/greenhouse01/climate/temperature
farm/greenhouse01/irrigation/valve01/cmd
farm/barn02/environment/co2
订阅时可以使用两种通配符。单层通配符 + 匹配一个层级,例如 farm/+/soil/moisture 可匹配 greenhouse01、greenhouse02 等所有棚室的土壤湿度;多层通配符 # 匹配剩余所有层级,且只能出现在主题末尾,例如 farm/greenhouse01/# 可接收该棚室下全部数据。通配符只能用于订阅,发布消息时主题中不允许出现 + 和 #。
设计主题时有几条经验:层级从大到小、语义稳定,避免把易变的时间戳或随机数放进主题;控制指令与遥测数据分开,例如遥测用 .../telemetry、指令用 .../cmd;不要用 # 订阅整个 farm/# 作为长期方案,设备规模变大后 Broker 和客户端的压力都会明显上升。另外,以 $ 开头的主题(如 $SYS/)是 Broker 系统主题,普通业务主题不要占用。
QoS 等级:按业务选可靠性
MQTT 定义了三个服务质量等级,权衡的是“消息能否到达”和“开销大小”:
| QoS | 语义 | 典型交互 | 农业场景建议 |
|---|---|---|---|
| 0 | 最多一次,可能丢失 | 发布即发送,不确认 | 高频环境数据、允许偶发丢点的曲线采集 |
| 1 | 至少一次,可能重复 | PUBLISH / PUBACK | 土壤湿度上报、一般状态量,需做幂等处理 |
| 2 | 恰好一次,开销最大 | 四次握手 | 计费、阀门开关等不容重复执行的指令 |
实际选择时,QoS 由发布和订阅两端共同决定,最终生效的是两者中较低的一级。例如传感器以 QoS 1 发布,订阅端以 QoS 0 订阅,则消息按 QoS 0 投递。对灌溉阀门这类执行指令,更稳妥的做法是使用 QoS 1 并在应用层携带指令序号,控制器收到后回执,重复序号直接丢弃,从而在“至少一次”的基础上实现业务幂等,而不是一味追求 QoS 2 带来的握手开销。
保留消息:让新订阅者立刻拿到最新状态
发布者发布消息时若设置 retain 标志,Broker 会为该主题保存最后一条保留消息。之后任何新订阅该主题的客户端,都会立即收到这条消息。农业场景中,这非常适合表达“当前状态”:阀门当前是开还是关、补光灯当前亮度、棚室当前温度。手机应用刚上线时,不必等待下一次上报就能显示最新值。
使用保留消息要注意两点:一是每个主题只保留最后一条,历史数据仍需依赖数据库;二是清除保留消息的方法是向同一主题发布一条空载荷的保留消息。对于状态类主题,建议设备在状态变化时发布保留消息,并周期性重发以刷新;对于高频遥测主题,一般不建议开启保留,避免 Broker 为大量主题长期保存数据。
会话与遗嘱消息:断线也要可感知
MQTT 会话(Session)保存的是订阅关系和未确认消息等状态。客户端连接时可以设置 Clean Session(MQTT 5 中为 Clean Start 加会话过期时间)。设为 false 时,Broker 会保留该客户端的订阅,并在其离线期间缓存 QoS 1/2 的消息,待其重连后补发。对于网络不稳定的田间网关,关闭清理会话可以减少重连后重新订阅的麻烦,也能接住离线期间的关键指令;但缓存量要有上限意识,避免长期离线导致消息堆积。
遗嘱消息(Will Message)是客户端在连接时预先登记的一条消息,当 Broker 检测到该客户端异常断开(如网络中断、设备掉电,且未正常发送 DISCONNECT)时,由 Broker 代为发布。农业场景中,可以把遗嘱主题设为 farm/greenhouse01/status/online,载荷为 offline,并设置 retain,这样监控端一旦收到该消息就能立即判断设备失联。与之配合,设备上线后向同一主题发布 online 的保留消息,就形成了一套简单的在线状态机制。
把六个概念串成一条农业链路
以一个温室土壤湿度采集与灌溉联动为例:传感器每 30 秒向 farm/greenhouse01/soil/moisture 发布一次读数,QoS 1,不保留;灌溉控制器订阅 farm/greenhouse01/soil/moisture,当湿度低于设定阈值(示例设为 35%)时,向 farm/greenhouse01/irrigation/valve01/cmd 发布开启指令,QoS 1 并携带指令序号;阀门执行后向 .../valve01/state 发布保留消息,让监控端随时看到当前开关状态。设备连接时登记遗嘱主题 farm/greenhouse01/status/online,载荷 offline 且 retain,上线后发布 online 覆盖。这样,数据上报、指令下发、状态查询和失联告警就都落在同一套主题体系里。
+。掌握这六个概念后,再看具体的连接参数、心跳与认证配置,就能理解每一项设置背后的业务含义,而不是机械照抄示例。