3. 设备接入协议选型

在 Azure IoT Hub 中,设备侧可用的接入协议主要有三种:MQTT、AMQP 和 HTTPS。它们并不是“谁替代谁”的关系,而是面向不同约束条件的三条通道。选型的本质,是在连接模型、消息方向、功耗与网络开销、开发复杂度、防火墙友好度之间做取舍。理解这一点,比记住“MQTT 适合设备、AMQP 适合服务端”这类结论更重要。

三种协议的连接特性差异

MQTT 是面向设备的轻量级发布/订阅协议,基于 TCP,默认端口 8883(TLS)。设备与 IoT Hub 建立长连接后,通过订阅 devices/{deviceId}/messages/devicebound/# 接收云到设备消息,通过向 devices/{deviceId}/messages/events/ 发布遥测。它的报文头最小仅 2 字节,长连接让云端可以在毫秒级把指令推给设备,因此天然适合“设备常在线、需要双向通信”的场景。

AMQP 是面向服务端和企业集成的消息协议,同样基于 TCP 长连接,端口 5671(TLS)。它提供更丰富的流控、会话和链路语义,支持高效的多路复用,适合高吞吐、需要可靠投递和复杂路由的服务端应用。但在设备侧,AMQP 的协议栈更重,对内存和 CPU 的要求高于 MQTT,嵌入式设备通常不选它。

HTTPS 是请求/响应模型,端口 443。设备每次上报都要重新发起 TLS 连接(或复用连接但仍是请求-响应),无法由云端主动推送消息。设备要获取云到设备消息,只能轮询 GET /devices/{deviceId}/messages/devicebound。它的优势是几乎穿透所有防火墙和代理,实现简单,适合低频率、低功耗、只上报不接收的传感器。

MQTT / AMQP / HTTPS 接入特性对比 设备 / 客户端 MQTT 客户端 长连接 · 发布/订阅 AMQP 客户端 长连接 · 链路/会话 HTTPS 客户端 请求/响应 · 轮询 Azure IoT Hub MQTT 端点 8883 · TLS AMQP 端点 5671 · TLS HTTPS 端点 443 · TLS MQTT 特性 双向推送 · 报文头 2 字节起 适合常在线设备 · 低带宽 AMQP 特性 多路复用 · 流控 · 可靠投递 适合服务端 · 协议栈较重 HTTPS 特性 请求/响应 · 无法主动推送 穿透防火墙 · 适合低频上报 设备→云(上报) 云→设备(下发) 虚线表示云端主动下发路径;HTTPS 无此路径,需设备轮询

适用场景与工程取舍

如果设备需要接收云端指令,比如远程开关、参数下发、固件升级通知,MQTT 是首选。它保持长连接,云端消息可以立即到达设备,不需要设备反复询问。典型场景包括智能家居网关、工业 PLC 监控、车联网终端。工程上要注意:长连接会持续消耗设备电量,移动网络下还可能因 NAT 超时被断开,因此需要实现心跳(Keep Alive)和断线重连。IoT Hub 的 MQTT 心跳建议设置为 60 秒以内,重连采用指数退避,避免风暴式重连。

如果设备只上报数据、不需要接收指令,且上报频率很低(例如每小时一次),HTTPS 反而更合适。它不需要维持长连接,每次上报后连接释放,设备可以进入深度睡眠,功耗更低。同时 HTTPS 走 443 端口,几乎不会被企业防火墙拦截。代价是每次上报都要重新做 TLS 握手,单次开销比 MQTT 大,且无法接收云端消息。典型场景是农业土壤湿度传感器、水表抄表、环境监测节点。

AMQP 在设备侧较少使用,但在服务端接入场景中很有价值。例如后端服务需要从 IoT Hub 读取大量设备到云消息,或者向大量设备发送云到设备消息,AMQP 的多路复用和流控能力可以显著降低连接数。如果团队已有 AMQP 生态(如 RabbitMQ、Azure Service Bus),复用 AMQP 可以降低集成成本。但要注意,AMQP 客户端库通常比 MQTT 大,不适合资源受限的 MCU。

选型决策表

判断维度 MQTT AMQP HTTPS
连接模型 TCP 长连接 TCP 长连接 请求/响应
云端主动下发 支持 支持 不支持(需轮询)
默认端口 8883 5671 443
报文开销 低(2 字节起) 中 高(HTTP 头 + TLS)
设备资源占用 低 高 中
防火墙友好度 中 中 高
典型场景 双向通信设备 服务端集成 低频上报传感器

实操中的关键参数与判断依据

以 MQTT 接入为例,设备连接时需要提供三个要素:IoT Hub 主机名、设备 ID、SAS 令牌或 X.509 证书。连接字符串形如:

HostName=myhub.azure-devices.net;DeviceId=sensor-001;SharedAccessKey=xxxxx

MQTT 客户端连接时,ClientId 必须与 DeviceId 一致,Username 格式为 {hostname}/{deviceId}/?api-version=2021-04-12,Password 使用 SAS 令牌。如果使用 X.509 证书认证,则 ClientId 仍为 DeviceId,但不需要 Password,改为在 TLS 层提供客户端证书。连接成功后,设备应订阅 devices/{deviceId}/messages/devicebound/#,然后开始向 devices/{deviceId}/messages/events/ 发布遥测。

判断连接是否健康,可以观察三个信号:一是 MQTT 的 CONNACK 返回码,0 表示成功,4 表示用户名密码错误,5 表示未授权;二是 IoT Hub 的“设备连接状态”指标,在门户中可以看到设备是否在线;三是消息计数,如果遥测消息持续到达,说明链路正常。如果设备频繁掉线,优先检查 Keep Alive 是否小于 NAT 超时时间,以及 SAS 令牌是否过期。SAS 令牌默认有效期为 1 小时,设备应在过期前刷新,否则会被断开。

对于电池供电的传感器,如果上报间隔大于 30 分钟,建议优先评估 HTTPS;如果上报间隔小于 5 分钟且需要接收指令,MQTT 更合适。AMQP 一般只在服务端或网关侧使用,不建议直接跑在 MCU 上。

工程取舍的常见误区

第一个误区是“MQTT 一定比 HTTPS 省电”。实际上,如果设备大部分时间在睡眠,HTTPS 每次唤醒后完成上报再断开,平均功耗可能低于 MQTT 长连接的心跳维持。第二个误区是“AMQP 性能最好,所以设备也用 AMQP”。AMQP 的吞吐优势体现在服务端多路复用,设备侧单连接场景下,MQTT 的轻量报文反而更高效。第三个误区是“HTTPS 不能接收云端消息”。严格说,HTTPS 不能主动推送,但设备可以通过轮询获取,只是实时性差、开销大,不适合需要快速响应的场景。

最终选型应回到三个问题:设备是否需要接收云端指令?设备资源是否足以维持长连接?网络环境是否允许非 443 端口?回答完这三个问题,协议选择基本就确定了。如果三个条件都偏向“是”,选 MQTT;如果都偏向“否”,选 HTTPS;如果设备是网关或服务端,再考虑 AMQP。