深入对比 MQTT、AMQP 与 HTTP/HTTPS:IoT-For-Beginners 第四课课后任务的协议选型指南
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
本文围绕《IoT-For-Beginners》入门系列第四课「将设备接入互联网」的课后作业展开,系统对比 MQTT 与 AMQP、HTTP/HTTPS 三大 IoT 通信协议。文中将以仓库中夜灯(nightlight)项目的 MQTT 实现为参照,从功耗、安全、断连消息持久化三个核心维度给出可执行的对比框架,帮助读者在真实 IoT 项目中做出正确的协议选型。
说明:本文对应的作业原文位于 translations/bg/1-getting-started/lessons/4-connect-internet/assignment.md(英文原版见 1-getting-started/lessons/4-connect-internet/assignment.md),其完整课程主体在 1-getting-started/lessons/4-connect-internet/README.md。
作业背景:为什么要比较 MQTT 与其他协议
第四课的核心是让读者理解 IoT 设备如何通过标准通信协议连接到云端服务。课程主体内容围绕 MQTT 展开——它是一种轻量级的、开放标准的消息传递协议,于 1999 年为监控输油管道而设计,15 年后由 IBM 发布为开放标准。MQTT 采用"单个 broker、多个客户端"的模型:所有客户端连接到 broker,消息通过具名主题(topic)路由,发布者向主题发布消息,订阅该主题的所有客户端都会收到消息。
课后作业要求学生完成一个研究型任务:将 MQTT 与另外两类常见协议——AMQP 和 HTTP/HTTPS——进行对比(compare and contrast),并重点从三个维度展开分析:
- 功耗(power usage)——协议对设备电池续航的影响;
- 安全(security)——协议提供的身份认证与加密能力;
- 消息持久性(message persistence)——连接中断时消息是否会丢失。
作业的评分标准(Rubric)也按此设计:分别对"AMQP vs MQTT"和"HTTP/HTTPS vs MQTT"两组对比评分,能够覆盖全部三个维度为"优秀",只覆盖两个维度为"合格",仅覆盖一个维度则"需要改进"。也就是说,一份完整的作业答案必须逐项给出这两组协议在功耗、安全、断连持久性上的差异结论,本文即为这一任务提供可直接参考的技术素材与仓库佐证。
MQTT 的关键特性回顾(对比基准)
在展开对比之前,先回顾课程中已经建立的 MQTT 知识基线,这些特性正是后续对比的参照物。课程 1-getting-started/lessons/4-connect-internet/README.md 中提到:
- 主题与通配符:主题具有层级结构,客户端可用通配符订阅多个层级,例如温度遥测发到
/telemetry/temperature、湿度发到/telemetry/humidity,云端应用订阅/telemetry/*即可同时接收两类数据; - 服务质量(QoS):MQTT 提供三档 QoS——至多一次(fire and forget)、至少一次(确认投递)、恰好一次(两阶段握手保证仅投递一份);
- 无消息队列:尽管名字里有"Message Queueing",MQTT 本身并不支持消息队列。客户端断开期间发送的消息不会在重连后自动补发(除了已在 QoS 流程中处理的消息);但消息可设置retained 标志,broker 会保存该主题上最后一条带此标志的消息,并在新客户端订阅时推送给它;
- 保活机制(keep alive):在消息间隔较长时检测连接是否仍然存活;
- 连接安全:MQTT 连接可以是公开开放的,也可以用用户名/密码或证书进行加密和认证;
- 传输层:MQTT 基于 TCP/IP,与 HTTP 底层协议相同但使用不同端口;也可通过 WebSocket 承载以适配浏览器或受防火墙限制的场景。
课程的实践环节在仓库中留有完整的可运行代码,它们展示了 MQTT 在"物联网夜灯"上的真实用法,可以作为对比时"MQTT 侧"的具体证据:
- MQTT 连接与遥测发布(Python 虚拟设备):1-getting-started/lessons/4-connect-internet/code-mqtt/virtual-device/nightlight/app.py
- MQTT 连接与命令订阅(Python 虚拟设备):1-getting-started/lessons/4-connect-internet/code-commands/virtual-device/nightlight/app.py
- 服务端订阅遥测、发布命令(Python):1-getting-started/lessons/4-connect-internet/code-commands/server/app.py
- Wio Terminal(Arduino/C++)端到端实现:1-getting-started/lessons/4-connect-internet/code-commands/wio-terminal/nightlight/src/main.cpp
以服务端代码为例,code-commands/server/app.py 完整演示了 MQTT 的"订阅遥测→决策→发布命令"闭环:
mqtt_client = mqtt.Client(client_name) mqtt_client.connect('test.mosquitto.org') mqtt_client.loop_start() def handle_telemetry(client, userdata, message): payload = json.loads(message.payload.decode()) print("Message received:", payload) command = { 'led_on' : payload['light'] < 300 } print("Sending message:", command) client.publish(server_command_topic, json.dumps(command)) mqtt_client.subscribe(client_telemetry_topic) mqtt_client.on_message = handle_telemetry while True: time.sleep(2)对应地,设备侧代码(code-commands/virtual-device/nightlight/app.py)每 5 秒向id + '/telemetry'主题发布一次{"light": <数值>}遥测,并订阅id + '/commands'主题,根据led_on字段控制 LED。两侧共用同一个id前缀命名主题——README.md 特别强调:服务端代码中的<ID>必须与设备端一致,否则订阅/发布就会落在错误主题上。Wio Terminal 版本则把同样的逻辑用 C++ 表达:PubSubClient负责 MQTT,ArduinoJson负责编解码,主题同样在 config.h 中定义为ID + "/telemetry"与ID + "/commands"。
这些代码展示的 MQTT 特点(轻量 JSON 载荷、单一 broker、主题路由、发布/订阅)正是后续对比中 MQTT 一方的基准画像。
MQTT 与 AMQP 的对比
AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一种面向消息的开放标准协议。与 MQTT 不同,AMQP 的核心定位是可靠的企业级消息传递,它原生支持消息队列、路由键(routing key)、交换器(exchange)与绑定(binding)等概念,并内建消息持久化、确认(acknowledgement)与事务能力。二者在以下三个维度上差异显著。
功耗对比
- MQTT 胜出。MQTT 为低功耗、低带宽场景而生:报文头极小(最小仅 2 字节),客户端与 broker 之间保持长连接,空闲时仅需周期性发送很小的 keep-alive 包即可维持连接,非常适合电池供电的传感器节点。
- AMQP 开销更大。AMQP 的帧结构、复杂的连接握手与多协议层次使其报文头部更大、协商更重,对微控制器等资源受限设备不友好。从仓库实践看,课程在 Wio Terminal(Cortex-M4F 微控制器)这类低算力设备上选择 MQTT(code-commands/wio-terminal/nightlight/src/main.cpp)而非 AMQP,正是功耗与资源约束下的典型取舍。
安全对比
- 两者都支持 TLS 加密传输与用户名/密码或证书认证,安全能力大致相当。MQTT 的差异点在于:其轻量连接安全基于 MQTT 规范中的 CONNECT 报文认证字段;而 AMQP 的安全模型与 SASL(简单认证与安全层)深度集成,更便于嵌入企业级统一身份体系。课程同时提醒:作业中使用的公共测试 broker
test.mosquitto.org是公开且不安全的,任何人可能监听你发布的内容,绝不可用于需要保密的敏感数据(见 README.md)——这一提醒对 AMQP 同样适用:无论使用哪种协议,公共 broker/服务都不能承载隐私数据。
断连时的消息持久性对比
- AMQP 原生具备持久化能力。AMQP 的消息队列模型支持消息落盘、持久订阅与消息确认,客户端断线期间 broker 会为其保留消息,重连后可继续消费,这与 AMQP"面向可靠企业集成"的定位一致。
- MQTT 需要显式配置。正如课程所述,MQTT 本身不支持消息队列,客户端断线期间的消息默认不会补发;如需近似持久性,只能依靠 retained 消息(broker 保存每个主题最后一条带 retained 标志的消息,供后来订阅者获取最新状态)或由应用层自行实现消息重放。对"断连期间全部消息都不丢失"的强可靠性场景,AMQP 原生模型更有优势。
对比结论(可直接用于作业):设备端资源紧张、电池供电、消息可容忍少量丢失时选 MQTT;需要企业级消息队列、严格的消息持久化与路由灵活性、且设备算力/供电充足时选 AMQP。就"夜灯"这类场景而言,MQTT 的轻量与 retained 消息(保证新接入设备立即拿到最新灯控状态)已经足够。
MQTT 与 HTTP/HTTPS 的对比
HTTP/HTTPS 是最普及的 Web 协议:HTTPS 在 HTTP 之上叠加 TLS 加密。几乎所有 IoT 设备都具备 HTTP/HTTPS 客户端能力,因此它也常被用作设备与云之间的传输方式,但其"请求-响应"模型与 MQTT 的"发布-订阅"模型存在本质差异。
功耗对比
- MQTT 更省电。MQTT 客户端建立长连接后持续保持连接,消息开销小;HTTP 则是"请求-响应"模式,客户端每次发送数据都要重新建立 TCP 连接(或维持连接池)、携带完整的 HTTP 报文头(含 Cookie、User-Agent 等大量元数据),报文体积远大于 MQTT。对电池供电、需要频繁上报数据的传感器,MQTT 的低开销显著延长续航。
- 反过来,如果设备极少上报数据(例如每天仅几次),HTTP/HTTPS 的"连接即用、发完即断"反而没有持续的保活开销,此时两者功耗差距缩小。这也是课程中"多久发送一次遥测"讨论的意义所在——README.md 明确指出:测量频率越高,功耗、带宽、数据量与云端处理成本都越高,需要"测够但不测太频繁"。
安全对比
- HTTPS 全面占优。HTTPS 通过 TLS 提供传输加密、服务器身份验证,并可通过客户端证书实现双向认证;由于继承了 Web 生态,HTTPS 还天然兼容 OAuth2、API Key 等成熟认证体系。而 MQTT 的 TLS 支持虽然存在(课程提到可用用户名/密码或证书加密),但在默认配置下 MQTT 常以明文运行(如公共测试 broker 的 1883 端口),需要显式启用 TLS 才安全。
- 需要注意:作业评分关注的是"协议本身能提供什么",所以在 HTTPS vs MQTT 的安全对比中应写"HTTPS 默认即加密、MQTT 需显式配置 TLS",而不是得出"MQTT 不安全"的绝对结论——两者在正确配置下都能实现安全通信。
断连时的消息持久性对比
- HTTP/HTTPS 没有服务端消息持久性。请求-响应模型下,请求要么送达、要么失败,客户端断线期间的请求根本不会被服务器"记住";服务端也无从向离线客户端主动推送消息。要实现"云→设备"的下行指令,HTTP/HTTPS 只能靠设备轮询(polling)拉取,这既增加延迟也增加功耗。
- MQTT 天然支持下行推送。设备与 broker 的长连接使云端可随时向设备发布命令,retained 消息还能让离线后重连的设备立即获得最新状态。课程中夜灯的命令控制(
/commands主题)就是这种"云→设备推送"的直接体现。若必须用 HTTP/HTTPS 实现类似效果,应用层需要额外的"消息暂存+设备轮询拉取"机制。
对比结论(可直接用于作业):仅需设备向云单向上报、频率低、且应用层可容忍失败重试时,HTTP/HTTPS 简单直接且安全默认开箱即用;需要双向实时通信(遥测上行 + 命令下行)、低功耗长连接、以及断连重连后的状态同步时,MQTT 明显更优。
三协议综合对比速查表
下表汇总三个维度上的对比结论,可直接作为作业的结论性材料:
| 对比维度 | MQTT | AMQP | HTTP/HTTPS |
|---|---|---|---|
| 通信模型 | 发布/订阅,broker 路由,主题寻址 | 发布/订阅 + 消息队列,交换器/路由键 | 请求/响应(HTTPS 即加密版 HTTP) |
| 功耗 | 极低,报文头小、长连接、保活开销小 | 较高,帧与握手开销大 | 中等到高,报文头大、轮询/频繁建连耗电 |
| 安全 | 支持 TLS、用户名/密码、证书,但需显式配置 | 支持 TLS、SASL 认证,企业级身份集成 | HTTPS 默认 TLS 加密,生态认证体系成熟 |
| 断连持久性 | 原生无队列;可借 retained 消息保留"最新一条",应用层可自行补发 | 原生消息队列 + 持久化 + 确认,断线消息可保留 | 无服务端持久性,下行需轮询,断线数据由应用层负责 |
| 典型适用 | 电池供电传感器、MCU 设备、双向遥测/命令 | 企业集成、金融/物流等强可靠性消息系统 | 上报型设备、Web 生态对接、低频数据 |
三个维度的分析要点:如何展开你的对比论证
为了让作业回答达到"优秀"档(覆盖全部三个维度),建议按照以下要点组织论证:
- 功耗:结合"设备是什么"来分析——MCU(如 Wio Terminal)内存与供电极其有限,必须选择报文开销最小的协议;单板机(如 Raspberry Pi)或常供电设备约束较小。同时考虑上报频率:高频上报下 MQTT 长连接优势明显;极低频上报下 HTTP/HTTPS 也未必不可接受。
- 安全:明确区分"默认状态"与"可配置能力"。MQTT 明文 1883 端口与公共 broker 是不安全的默认配置;HTTPS 默认加密是"开箱即安全"。指出课程 README.md 对公共 broker 的警告,论证任何协议的公共端点都不可用于敏感数据。
- 断连消息持久性:引用课程关于"连接丢失"的讨论(README.md 的 Loss of connectivity 小节):温控器可以丢弃旧读数(新读数覆盖旧值),而工业机械的遥测数据需要全部保留用于异常检测与预测性维护。据此说明:需要"全部消息不丢"选 AMQP 原生队列;需要"最新状态不丢"用 MQTT retained 消息;HTTP/HTTPS 则完全依赖应用层自行实现。
结合仓库源码的延伸阅读
- 完整课程内容(含协议理论、遥测、命令与挑战题):1-getting-started/lessons/4-connect-internet/README.md
- 服务端订阅遥测并打印消息(基础版):1-getting-started/lessons/4-connect-internet/code-server/server/app.py
- 服务端决策并下发
led_on命令(完整闭环):1-getting-started/lessons/4-connect-internet/code-commands/server/app.py - 虚拟设备发布遥测(MQTT 连接基础版):1-getting-started/lessons/4-connect-internet/code-mqtt/virtual-device/nightlight/app.py
- 虚拟设备订阅命令并控制 LED: 1-getting-started/lessons/4-connect-internet/code-commands/virtual-device/nightlight/app.py
- Wio Terminal 设备端 C++ 实现(发布遥测 + 订阅命令):1-getting-started/lessons/4-connect-internet/code-commands/wio-terminal/nightlight/src/main.cpp
- Wio Terminal 的 MQTT 主题与 broker 配置:1-getting-started/lessons/4-connect-internet/code-commands/wio-terminal/nightlight/src/config.h
- 课程配套图形笔记(第四课速记图):sketchnotes/lesson-4.jpg
参考实现提示:若想自己动手验证"断连持久性"这一维度,可尝试按 README.md 结尾的建议,用 Mosquitto 自建本地 broker(默认禁止匿名连接且不允许外部访问,可在
mosquitto.conf中配置listener 1883 0.0.0.0与allow_anonymous true放开),再分别测试 MQTT retained 消息与 AMQP 持久队列在客户端断线重连后的行为差异。
【免费下载链接】IoT-For-Beginners12 Weeks, 24 Lessons, IoT for All!项目地址: https://gitcode.com/GitHub_Trending/io/IoT-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考