2. MQTT协议核心概念

在灌溉云平台中,田间控制器、土壤墒情传感器、气象站、阀门执行器和云端服务之间需要一种轻量、可靠且适合弱网环境的通信方式。MQTT 正是这类场景的主流选择。理解 MQTT 的核心概念,不能停留在“发布订阅”四个字上,而要把它落到灌溉系统的具体对象、主题命名、消息可靠性和异常处理上。本节围绕发布/订阅模型、主题与通配符、QoS 等级、保留消息、会话与遗嘱消息六个概念,结合灌溉场景逐一展开。

一、发布/订阅模型:解耦设备与业务

MQTT 采用发布/订阅(Pub/Sub)模型,消息不直接从发送方送到接收方,而是由发布者发送到 Broker(消息代理),再由 Broker 根据主题分发给订阅者。发布者与订阅者互不知道对方的存在,只与 Broker 建立连接。这种解耦对灌溉系统非常重要:一个土壤湿度传感器只需把数据发布到固定主题,不需要知道有多少个业务系统在消费它;云端灌溉决策服务、手机 App、大屏看板可以各自订阅同一主题,互不影响。

在灌溉场景中,典型角色划分如下:田间传感器是发布者,发布墒情、流量、压力数据;云端决策服务既订阅传感器数据,又向阀门控制器发布开关指令;阀门控制器订阅指令主题并发布执行结果;手机 App 作为订阅者展示状态。Broker 通常部署在云平台侧,所有设备通过 TCP/TLS 长连接接入。发布/订阅模型带来的直接好处是:新增一个“节水统计”服务时,只需订阅相关主题,无需改动任何现场设备。

二、主题与通配符:灌溉数据的命名规范

主题(Topic)是 MQTT 消息的路由地址,采用斜杠分隔的层级结构,区分大小写。良好的主题设计是灌溉平台可维护性的基础。建议按“区域/设备类型/设备编号/数据方向”组织,例如:

irrigation/zone01/soil/sensor03/moisture
irrigation/zone01/valve/valve02/cmd
irrigation/zone01/valve/valve02/state
irrigation/zone02/weather/station01/rainfall

订阅时可以使用两种通配符:加号 + 匹配单层,井号 # 匹配多层且只能出现在末尾。例如云端要接收所有区域的阀门状态,可订阅 irrigation/+/valve/+/state;要接收某区域全部数据,可订阅 irrigation/zone01/#。需要注意,通配符只用于订阅,发布主题必须是具体主题,不能含通配符。实际工程中应避免用 # 订阅全部主题,否则海量无关消息会压垮客户端;同时主题层级不宜过深,建议控制在 5 层以内,便于排查。

三、QoS 等级:按灌溉业务选择可靠性

MQTT 定义了三个服务质量等级。QoS 0“最多一次”,消息发出即不管,可能丢失;QoS 1“至少一次”,通过 PUBACK 确认,可能重复;QoS 2“恰好一次”,通过四次握手保证不丢不重,开销最大。灌溉系统中不同业务对可靠性的要求差异明显:周期性上报的土壤湿度数据,丢一两条不影响趋势判断,可用 QoS 0;阀门开关指令关系到我是否误灌、漏灌,应使用 QoS 1,并在应用层用指令序号做幂等处理,防止重复执行;计费或用水量结算类消息若要求严格,可考虑 QoS 2,但多数灌溉平台用 QoS 1 加业务去重即可满足。

需要提醒的是,QoS 是端到端链路上发布端与订阅端协商的结果,实际生效等级取发布与订阅两者中的较小值。因此配置时不能只改发布端,订阅端也要匹配。

四、保留消息:让新订阅者立即拿到最新状态

保留消息(Retained Message)是指 Broker 为某个主题保存最后一条带 retain 标志的消息,当新的订阅者订阅该主题时,Broker 立即把这条消息推送给他。灌溉场景中,阀门当前开关状态、控制器在线状态非常适合用保留消息。假设阀门状态发布到 irrigation/zone01/valve/valve02/state 并设置 retain=true,那么手机 App 无论何时打开,订阅后立刻能看到阀门“关闭”这一最新状态,而不必等待下一次状态上报。注意保留消息只保留最后一条,且发布空载荷的保留消息可清除该主题的保留值。保留消息不适合承载高频时序数据,否则 Broker 存储和状态语义都会混乱。

五、会话与遗嘱消息:应对断线与异常

MQTT 会话(Session)由客户端标识 ClientID 关联。连接时可设置 Clean Session(MQTT 3.1.1)或 Clean Start 加会话过期时间(MQTT 5.0)。若关闭清理会话,Broker 会为客户端保存订阅关系和未确认的 QoS 1/2 消息,设备断线重连后能继续接收,避免灌溉指令在弱网抖动中丢失。田间 4G/NB-IoT 信号不稳定,建议阀门控制器使用持久会话,并配合较短的 Keep Alive(如 60 秒)及时发现掉线。

遗嘱消息(Will Message)是客户端连接时预先注册的一条消息,当 Broker 检测到该客户端异常断开(未发送正常 DISCONNECT)时,自动代其发布。灌溉场景中,可为每个阀门控制器设置遗嘱主题 irrigation/zone01/valve/valve02/online,遗嘱载荷为 offline,并设置 retain=true。这样一旦控制器失联,云端和 App 会立即收到离线状态,运维人员可及时排查,避免“以为在灌溉、实际阀门未动作”的风险。正常关机时应主动发布 online=false 或发送 DISCONNECT,避免遗嘱误触发。

灌溉云平台 MQTT 发布/订阅与关键机制 MQTT Broker 主题路由 / 保留消息存储 会话保持 / 遗嘱触发 土壤墒情传感器 发布 moisture QoS 0 气象站 发布 rainfall QoS 0 阀门控制器 订阅 cmd / 发布 state QoS 1 · 持久会话 遗嘱:offline 云端灌溉决策 订阅 + / # 发布阀门指令 手机 App 订阅 state(保留) 订阅 online 监控大屏 订阅 zone01/# 展示实时状态 传感器数据上行 阀门指令/状态 云端/应用订阅 指令下发 实线:发布方向 虚线:订阅/下发方向 保留消息:state 与 online 主题保存最后状态 遗嘱:控制器异常断开时 Broker 代发 offline

六、把六个概念落到一次灌溉控制中

假设 zone01 的土壤湿度低于阈值 30%,云端决策服务需要开启 valve02 灌溉 10 分钟。完整消息流可以这样设计:传感器以 QoS 0 发布 irrigation/zone01/soil/sensor03/moisture,载荷为 JSON {"value":28,"ts":1710000000};决策服务订阅该主题后判断触发,向 irrigation/zone01/valve/valve02/cmd 以 QoS 1 发布 {"action":"open","duration":600,"seq":1001};阀门控制器持久会话在线,收到指令后执行,并向 irrigation/zone01/valve/valve02/state 以 QoS 1、retain=true 发布 {"state":"open","seq":1001};App 订阅该主题后立即收到保留的最新状态。若控制器在灌溉中失联,Broker 触发遗嘱,向 irrigation/zone01/valve/valve02/online 发布 retain=true 的 offline,云端据此告警并停止后续排程。

主题设计建议:设备侧只发布自己产生的数据,指令主题与状态主题分离;保留消息只用于“当前状态”类主题;QoS 1 指令务必携带 seq 序号做幂等;持久会话与遗嘱消息应成对配置,才能同时覆盖“断线续传”和“异常告警”。
常见误区:用 # 订阅全部主题导致客户端被无关消息淹没;把高频墒情数据设为保留消息造成状态语义混乱;只改发布端 QoS 而忽略订阅端协商取小值;控制器正常关机未发 DISCONNECT 导致遗嘱误报离线。

掌握这六个概念后,灌溉云平台的通信设计就有了清晰的抓手:用发布/订阅解耦角色,用主题与通配符组织数据,用 QoS 匹配业务可靠性,用保留消息解决“新订阅者看不到当前状态”,用持久会话和遗嘱消息覆盖弱网断线与设备异常。后续的指令下发、数据入库和告警联动,都建立在这套消息语义之上。