☰
IoT 系统架构全景:从传感器到云,一张图讲清“端-边-云“
2026/10/12 2:23:12 网站建设 项目流程

IoT 系列第 1 篇。在《09_无线通信》里我们解决了"数据怎么飞出去",这一篇往上抬一层,看整张地图。

适用人群:玩过 STM32 或 ESP32、能读传感器、能连 Wi-Fi,但一被问"你这套东西架构是怎样的"就答不上来的同学。不需要服务器经验,Docker 命令我会从 0 给。

读完你能得到:

  • 一张能默出来的端-边-云三层架构图,面试画在白板上不心虚;
  • “为什么中间非要多一个网关”——四个能折算成钱或可靠性的理由;
  • 常见软硬件的对号入座(STM32/ESP32/树莓派/EMQX/云平台各站哪一层);
  • 一次完整数据流的六步走,知道你的字节过了几道手;
  • 协议选型视角:MQTT / CoAP / HTTP / LwM2M 不是四选一,是各管一段;
  • 半小时在本机跑起来的最小端边云(ESP32 + EMQX Docker + Node-RED)。

没看过无线通信那几篇也能懂的核心:传感器只负责"把物理量变成数字",数字要变成"别人能用的信息",中间还隔着链路、协议、网关、平台四层。本文讲的就是这四层怎么分工。


一、我曾经以为"IoT = ESP32 连 Wi-Fi 发个 HTTP"

大二那年我做了个"教室温湿度监测":ESP32 读 SHT30,每 10 秒POST一个 JSON 到我自己写的 Flask 接口,网页能看曲线。当时我觉得物联网不过如此。后来两个"看起来差不多"的需求把我打醒了。

第一个是学校试验田的土壤墒情。田里没 Wi-Fi、没市电,要太阳能 + 电池活一学期。我原来的方案直接作废:一台设备开一个 HTTP 长连,光 TCP 握手的开销都比一包数据大。而且 20 个节点各自直连我的云服务器,20 条 TCP 连接 24 小时挂着——云是我自己的,钱包也是我自己的。

第二个是智慧路灯。要求是"天黑自动亮、人走过加亮、断网了也要亮"。我第一反应是"云端写个规则呗",老师问我一句:校园网断了,你的路灯是不是就全瞎了?我答不上来。这类"断网也要能工作"的需求,本质上是要求判断逻辑不在云上,而在路灯旁边。

这两个需求把我逼出了"设备直连云"的单一思维。真实的 IoT 系统里,设备和云之间几乎总是夹着一层东西,它叫边(Edge)。加上它之后,原本无解的问题突然有解了:

  • 田里 20 个电池节点不用各自连云,用 BLE 或 LoRa 甩给田埂上那个有电有网的网关统一上行——省电、省流量、省连接数;
  • 路灯的联动规则写在本地网关里,断网只是"上不了报",灯照样亮;
  • 上行数据先在网关滤波、聚合、只传变化量,流量费直接降一个数量级。

我没有量产经验,这些是我在课设和啃文档过程中整理的。但"端-边-云"不是我发明的,它是行业通用语言——你去面试,白板上画出来的那张图应该跟本文图 1 同一个骨架。


二、前置概念表:先把这几个词对齐

术语白话解释一句话记住它
端(Device / Node)真正接触物理世界的板子:采集数据或执行动作大多数端节点压根不会直接上网,也上不起网
边(Edge)端和云之间的"中转 + 处理站"。有电、有网、算力比端强它不是"转发器",是会思考的中转站
云(Cloud)远端服务器集群:存储、分析、下发、对接业务长处是算力和全局视角,短处是离设备太远
BrokerMQTT 的消息中转服务器,按主题转发设备之间从不直连,都在跟 Broker 说话
网关(Gateway)协议转换器:把 BLE/Modbus/Zigbee 翻译成 MQTT/HTTP网关是边最常见的物理形态;"边"还包括网关里跑的逻辑
上行 / 下行设备→云叫上行(遥测),云→设备叫下行(命令)上行求"稳",下行求"快"
主题(Topic)MQTT 里消息的地址,agri/gw01/telemetry,用/分层主题设计好不好,决定以后加设备痛不痛苦

⚠️ 最容易搞混的一对:"边"是逻辑层,"网关"是具体设备。一个树莓派上跑 Mosquitto + Node-RED + 联动脚本,它既是网关(硬件),也是边(逻辑)。阿里云的"边缘计算实例"则是把边做成软件塞进别的机器——层还在,只是不再是一台看得见的盒子。


三、端-边-云三层全景图

[图 1] IoT 系统"端-边-云"三层全景(面试白板上画的那张) ┌──────────────────────────── 云 CLOUD ────────────────────────────┐ │ ┌─────────────────┐ ┌──────────────┐ ┌──────────────────┐ │ │ │ 物联网平台 │ │ 规则引擎 │ │ 业务应用 │ │ │ │ EMQX / 阿里云IoT │──>│ 阈值告警 │──>│ 大屏 / App / MES │ │ │ │ 华为云 / OneNET │ │ 数据清洗 │ │ 时序数据库 │ │ │ └─────────────────┘ └──────────────┘ └──────────────────┘ │ └────────┼─────────────────────────────────────────────────────────┘ │ MQTT over TLS:1883 / 8883 │ ↑ 这一段是广域网,会断、会慢、按流量收费 ═════════╪══════════════════════════════════════════════════════════ │ 园区 / 现场局域网:通常免费、快,但地理范围有限 ┌──────────────────────────── 边 EDGE ────────────────────────────┐ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ 边缘网关(树莓派 / ESP32-S3 / 工控机 / 工业网关) │ │ │ │ ① 协议转换 BLE / Modbus / Zigbee / LoRa ⇄ MQTT │ │ │ │ ② 本地 Broker(可选)Mosquitto / EMQX,断网也能内部通信 │ │ │ │ ③ 边缘计算 滑动滤波、越限判断、聚合上报、单位换算 │ │ │ │ ④ 断网续传 本地队列 + SQLite / 文件缓存,联网后补传 │ │ │ │ ⑤ 本地联动 "温度>30 就开风扇",不依赖云 │ │ │ └───────────────────────────────────────────────────────────┘ │ └──────▲──────────────▲─────────────────────▲─────────────────────┘ │ │ │ BLE / Zigbee RS-485 / Modbus LoRa / 私有射频 ┌──────┴───────┐ ┌────┴───────┐ ┌──────┴────────┐ │ 温湿度节点 │ │ 电表 / 水表 │ │ 土壤墒情节点 │ │ STM32+传感器 │ │ 工业仪表 │ │ 电池 + 太阳能 │ └──────────────┘ └────────────┘ └───────────────┘ 端 DEVICES(数量多、资源少、大多不通 IP)

3.1 三层各自该干什么、不该干什么

判断一个功能放哪层,我的土办法是问三个问题:要不要全局信息?能不能容忍延迟?断网时还要不要工作?

层该它干的不该它干的典型软硬件
端采样、执行、本地安全联锁、低功耗休眠(Stop / Deep Sleep)、基础自检复杂规则判断、长连接、TLS 握手、大数据缓存STM32(F1/F4/L4/U5 按功耗算力选)、ESP32-C3/S3(自带 Wi-Fi/BLE)、nRF52(纯 BLE)
边协议转换、聚合/滤波、本地联动、断网续传、本地告警、固件分发跨站点全局分析、长期历史存储树莓派/香橙派(Linux + Docker)、ESP32-S3(轻量网关)、工业网关(RS-485/DI/DO)、跑 Mosquitto / EMQX / Node-RED
云海量存储、跨设备关联分析、用户权限、OTA 版本管理、对接业务毫秒级实时控制、单点高频联动阿里云 IoT / 华为云 / OneNET(托管);自建:EMQX / Mosquitto + 时序库(TDengine/InfluxDB)+ 规则引擎

⚠️平台差异:同样叫"边",ESP32-S3 和树莓派不是一个量级。ESP32-S3 几百 KB RAM、无 MMU、跑 FreeRTOS,让它做"本地 Broker + 一周缓存"是想多了;树莓派是瓦级功耗、GB 级内存,能干的多得多但费电、贵、要管系统。选硬件前先算清楚"要缓存多少"“要不要跑容器”,别上来就上树莓派,也别硬扛。

💡云端选型:托管平台的好处是"接入、鉴权、影子、OTA 都给你做好了",坏处是被绑死、按消息数收费、数据过别人手。自建全在自己手里、本地就能练手,代价是鉴权/高可用/监控自己扛。我的建议是先自建把 MQTT 搞明白,再学平台的封装——顺序反了,平台的"物模型"“影子”"Topic 类"你一个都看不懂。


四、为什么非要多一个"边":四个理由,逐个能算账

如果你以后只记得一句话,我希望是这句:边不是为了"多一层显得专业",它解决的都是能折算成钱或可靠性的问题。

4.1 省钱:带宽和云成本

假设一个大棚有50 个节点,每 30 秒上报一次 100 字节:

方案 A:50 个节点各自直连云(每个都开 TCP + TLS) 每包实际开销 ≈ 100 B 载荷 + 40 B TCP/IP 头 + ~30 B MQTT 头 + TLS 记录头 ≈ 200 B 往上 每天:50 × 2880 × 200 B ≈ 28.8 MB/天 ≈ 864 MB/月;服务器维持 50 条 TLS 长连接 方案 B:节点走 BLE/LoRa 给网关,网关每 5 分钟聚合发一包(约 2 KB) 每天:288 × 2 KB ≈ 0.58 MB/天 ≈ 17 MB/月;服务器只维持 1 条连接 → 流量降到约 1/50,连接数从 50 降到 1

数字是估算的,但数量级是对的:聚合 + 批量上传,是边缘层最直白的省钱方式。

4.2 省电:把最费电的活从电池节点身上拿走

《低功耗》那几篇的公式:平均电流 = Σ(各状态电流 × 停留时间) ÷ 周期。一次 MQTT 上报要 3~5 秒的高电流(含建连、TLS 握手),而一次 BLE 广播只要几十毫秒。把射频发射时长砍掉一两个数量级,续航直接翻倍。所以我那个"发 HTTP"的 ESP32 教室节点用市电毫无问题,一换电池架构就得改:电池端只做短距离低功耗通信,联网的重活交给有市电的网关。

4.3 断网续传:最容易被忽视,也最容易在验收时翻车

我第一次做户外项目时写的是:采样 → 连 Wi-Fi → 发 HTTP → 失败就丢弃。只要那 5 分钟网络抖一下,数据就永久没了。验收时对方问我"昨天下午 3 点到 4 点的数据呢",我只能说"那会儿断网了"。

[图 2] 断网续传的基本结构 采样 ──> 打时间戳 ──> 本地环形队列(内存 + 掉电保存到 Flash/SQLite) │ 联网?───────┤ 是 ─────────> 批量上行 → 收到确认 → 删除队列条目 否 ─────────> 继续攒,到上限就按策略丢最旧的

三个要点,每条都是踩过的:① 时间戳要在采样那一刻打,不是上传时打——否则断网一小时后补传的数据全挤在同一时刻,曲线是错的;② 队列要有上限,别把 Flash 写穿(和《17_存储》的写平衡、掉电保护是同一个问题);③ 补传要分批限速——断网两小时后一恢复灌几千条进去,轻则卡死自己,重则被 Broker 限流踢下线。

4.4 本地联动:呼应我在《项目实战_02》做的 BLE 网关

我在《项目实战_02:智能家居环境网关——ESP32 做 BLE 中心 + 本地联动》里干的事,用本篇的语言重述一遍:

[图 3] 同一个项目,两种架构 (a) 我最初的"云上联动"想法 传感器 ──Wi-Fi──> 云规则引擎 ──> 下发命令 ──> 执行器 断网 = 全瘫;每次联动绕一圈,延迟几百毫秒到几秒 (b) 实际做成的"本地联动"(边在起作用) 传感器 ──BLE──> ESP32 网关【规则:温度>28℃ 且 有人 → 开风扇】──> 执行器 └──MQTT──> 云(只负责记录和远程手动控制) 断网 = 只是上不了报,联动照常;延迟是毫秒级

这个经历让我彻底理解了"边":判断逻辑离被控对象越近,系统越可靠。云是"全局视角和记忆力",不是"反射神经"——你不会指望大脑皮层负责膝跳反射。


五、数据是怎么流过去的:一次上行 + 一次下行

[图 4] 一次完整闭环,六个阶段 ① 采集 传感器 → 数字量(I2C/SPI/ADC) ② 本地处理 标定、单位换算、滑动平均、剔除跳变、越限标记 ③ 协议封装 组 JSON/CBOR,加设备 ID、时间戳、序号、校验 ④ 上行 MQTT PUBLISH(QoS 1) → Wi-Fi/4G/LoRa → 网关 → Broker ⑤ 平台 解析、鉴权、入库、规则引擎判定、更新设备影子 ⑥ 下行控制 PUBLISH 到 cmd 主题 → 设备校验执行 → 回报新状态(回到 ①) 关键:⑥ 执行完必须回报,形成闭环。否则 App 上永远是"已发送", 你不知道设备到底开没开——而这个"回报"本身就是一次上行。

⚠️ 第 ③ 步新手最常踩:把所有东西塞进一个主题。比如device/data里一会儿温度一会儿电量一会儿心跳,靠解析 payload 区分。后果是没法用主题过滤(云端规则写得又臭又长)、retained 消息也没法用。主题要按"用途"分层,不是按"设备"打包。


六、协议选型:不是四选一,是各管一段

这是我最想纠正的误解。教程常把 MQTT/CoAP/HTTP/LwM2M 摆一排让你"选一个",但真实架构里它们常常同时出现,只是在不同的段上。

[图 5] 协议是分段的,不是互斥的 端 ────────────> 边 ────────────> 云 ──────────> 业务 BLE GATT MQTT over TLS HTTPS / AMQP / Kafka Modbus RTU (也可能直接 CoAP)数据库驱动 Zigbee / LoRa 私有帧 └─ 根本不是 IP 网络, └─ 这一段才是 └─ 跟嵌入式关系不大, 轮不到 MQTT MQTT 的主战场 是后端的事

所以听到"这设备用什么协议",第一个该问的是"从哪儿到哪儿"。

协议跑在报文开销模型该用的地方别用的地方
MQTTTCP(+TLS)固定头最小2 B发布/订阅,长连接,支持推送边↔云主力;遥测 + 下行命令;有市电设备电池 + NB-IoT 的极低频上报(心跳本身就费电,见《无线_03》)
CoAPUDP固定头4 B请求/响应(像精简 HTTP)电池设备 + 极受限网络;NB-IoT/LoRa 直连需要服务端主动推命令、对丢包零容忍的业务
HTTP(S)TCP文本头,动辄几百字节请求/响应,短连接偶尔取配置、下载固件、对接 Web 后端高频遥测(头比载荷大);下行实时控制
LwM2M通常在 CoAP 之上同 CoAP面向"资源"(如/3/0/1)设备管理:远程配置、固件升级、生命周期当"数据上报协议"用——那不是它的主场

💡一句话记忆:MQTT 管来回传数据,CoAP 管极省电地传一包,HTTP 管跟 Web 世界打交道,LwM2M 管管理设备本身。成熟平台里这四个往往同时在跑。

6.1 主题命名:现在多花 5 分钟,以后省 5 天

{产品}/{设备ID}/{方向}/{用途} agri/gw01/up/telemetry 上行:周期遥测 agri/gw01/up/event 上行:事件/告警 agri/gw01/up/reply 上行:命令执行结果(闭环!) agri/gw01/down/cmd 下行:命令 agri/gw01/status 状态(配合 retained + 遗嘱) 订阅侧:agri/gw01/down/#(这台的下行) agri/+/up/telemetry(所有设备遥测)

四条规矩:① 不以/开头(会产生空层级);② 主题里不放动态值(时间戳、随机数一律进 payload,否则主题树爆炸);③ 全小写 + 短横线,别混大小写;④ 主题里不放敏感信息,它是明文的,鉴权靠用户名/密码或证书。


七、动手:半小时搭一个最小端边云

这套我自己在笔记本上跑通过,不需要买云、不需要公网 IP,全在本机 Docker 里。

第 1 步:起一个本地 Broker(EMQX)

dockerrun-d--nameemqx\-p1883:1883\# MQTT over TCP-p8083:8083\# MQTT over WebSocket-p8084:8084\# MQTT over WSS-p8883:8883\# MQTT over TLS-p18083:18083\# Dashboard(Web 管理页)emqx/emqx:latestdockerlogs-femqx# 看日志确认起来了

浏览器打开http://localhost:18083,默认账号密码admin/public,首次登录会要求改掉默认密码。

⚠️ 后面让 ESP32 连这个 Broker 时,地址不能填localhost或127.0.0.1——那是 ESP32 自己。要用电脑在局域网里的 IP(ifconfig/ipconfig查)。这是"ESP32 连不上 EMQX"的头号原因,第二号是防火墙没放行 1883。

第 2 步:先用命令行验证 Broker 通了

sudoaptinstall-ymosquitto-clients# macOS: brew install mosquitto# 终端 A:订阅(模拟"云/应用"一侧)mosquitto_sub-h192.168.1.100-t'agri/#'-v# 终端 B:发布(模拟"设备"一侧)mosquitto_pub-h192.168.1.100-t'agri/gw01/up/telemetry'\-m'{"temp":26.5,"humi":61,"ts":1756000000}'-q1

终端 A 应立刻打印出这一条。意义:先把云侧打通再调设备,这样设备联不上时你能确定问题在设备侧。

第 3 步:ESP32 上报(最小可用版)

/* ============ ESP32 / ESP-IDF v5.x:最小 MQTT 上报 ============ * 前置:Wi-Fi 已连接并拿到 IP(esp_wifi 或 example_connect 均可) * 配置细节见本系列下一篇《MQTT 深度实战》 */#include<stdbool.h>#include<string.h>#include"mqtt_client.h"#include"esp_log.h"staticconstchar*TAG="app";staticesp_mqtt_client_handle_ts_client=NULL;staticvoidmqtt_event_handler(void*handler_args,esp_event_base_tbase,int32_tevent_id,void*event_data){esp_mqtt_event_handle_tevent=(esp_mqtt_event_handle_t)event_data;switch((esp_mqtt_event_id_t)event_id){caseMQTT_EVENT_CONNECTED:ESP_LOGI(TAG,"broker 已连接");esp_mqtt_client_subscribe(event->client,"agri/gw01/down/cmd",1);break;caseMQTT_EVENT_DATA:{/* ⚠️ event->topic / event->data 不以 '\0' 结尾,必须按长度拷贝 */chartopic[64];inttlen=event->topic_len;if(tlen>=(int)sizeof(topic))tlen=(int)sizeof(topic)-1;memcpy(topic,event->topic,(size_t)tlen);topic[tlen]='\0';ESP_LOGI(TAG,"收到 [%s] qos=%d : %.*s",topic,event->qos,event->data_len,event->data);/* 执行完记得往 .../up/reply 回报一次,形成闭环 */break;}caseMQTT_EVENT_DISCONNECTED:ESP_LOGW(TAG,"连接断开,esp-mqtt 默认会自动重连");break;default:break;}}voidmqtt_app_start(void){constesp_mqtt_client_config_tcfg={.broker.address.uri="mqtt://192.168.1.100",/* 换成你的局域网 IP */.credentials.client_id="esp32-gw01",/* 同 Broker 内必须唯一 */.session.keepalive=60,/* 秒 */.network.reconnect_timeout_ms=5000,.network.timeout_ms=10000,};s_client=esp_mqtt_client_init(&cfg);if(s_client==NULL){ESP_LOGE(TAG,"mqtt init 失败");return;}esp_mqtt_client_register_event(s_client,ESP_EVENT_ANY_ID,mqtt_event_handler,NULL);esp_mqtt_client_start(s_client);}/* 上报一包遥测(在采集任务里调用) */booltelemetry_publish(floattemp,floathumi,int64_tts_ms){if(s_client==NULL)returnfalse;charpayload[128];intn=snprintf(payload,sizeof(payload),"{\"temp\":%.1f,\"humi\":%.1f,\"ts\":%lld}",(double)temp,(double)humi,(longlong)ts_ms);if(n<=0||n>=(int)sizeof(payload))returnfalse;/* 格式化失败或截断 *//* QoS 1:要等 PUBACK。返回 >=0 的 msg_id 才算进了发送队列 */intmsg_id=esp_mqtt_client_publish(s_client,"agri/gw01/up/telemetry",payload,n,1,0);if(msg_id<0){ESP_LOGW(TAG,"publish 失败: %d(-2 = outbox 满,发的比网络快)",msg_id);returnfalse;}returntrue;}

第 4 步:用 Node-RED 当那个"云上应用"

npminstall-gnode-red&&node-red# 打开 http://localhost:1880# 或:docker run -d -p 1880:1880 --name nodered nodered/node-red

拖四个节点连成一条线,这就是云层在干的事:解析 → 存储 → 展示。

┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ mqtt in │──>│ json │──>│ function │──>│ debug / │ │ agri/# │ │ 解析字符串 │ │ 提取字段 │ │ chart │ └──────────┘ └──────────┘ └──────────┘ └─────────┘

mqtt in 节点填 Server192.168.1.100:1883、Topicagri/#、QoS 1;function 节点只写一行:

// Node-RED function 节点内(JavaScript)msg.payload={value:msg.payload.temp,ts:msg.payload.ts};returnmsg;

点 Deploy,再用mosquitto_pub发一次,debug 面板应立刻出现数据。到这一步你已跑通完整的"端 → 云 → 应用"链路——只不过"边"目前是空的。

第 5 步:把"边"加回来,做对比实验

  1. 不聚合:ESP32 每 2 秒发一包,去 EMQX Dashboard 看消息速率;
  2. 加上边:在 ESP32 里做 10 秒滑动窗口,只有"温度变化超 0.5 ℃ 或超过 30 秒没发"才上报;
  3. 对比 Dashboard 上的「消息数 / 分钟」。

你会看到一个数量级的差别,且数据几乎没有信息损失——这就是 4.1 那笔账的实物版。


八、新手必踩的 8 个坑

#坑现象 / 后果正确做法
1所有设备直连云,不考虑网关连接数爆炸、流量费高、电池撑不过一周先问"有没有市电、数量多少",10 个以上电池节点就该考虑边
2ESP32 里 Broker 地址填localhost/127.0.0.1连不上,日志一片超时填电脑的局域网 IP;确认防火墙放行 1883
3断网时直接丢数据网络一抖,这段时间数据永久缺失本地队列 + 采样时打时间戳 + 队列有上限 + 补传限速
4时间戳在上传时打,不是采样时打补传的历史数据全挤同一时刻,曲线是假的采样那一刻就打;或维护序号由平台还原
5所有消息塞进一个主题云端规则写不动、没法过滤、retained 用不了按{产品}/{设备}/{方向}/{用途}分层,一用途一主题
6主题以/开头,或把时间戳拼进主题多出空层级;主题树爆炸撑爆 Broker 内存不以/开头;主题只放稳定标识,动态值进 payload
7下行命令发出去就不管App 显示"已发送",不知设备有没有执行设备执行完回报.../up/reply,形成闭环
8边这层硬件选型拍脑袋树莓派做电池场景几小时没电;ESP32 硬扛一周缓存撑不住先算"缓存多大、要不要跑容器、功耗预算多少"再选

九、动手练一练

按顺序做。第 3 步和第 5 步是故意搞破坏——只有亲眼见过故障现象,以后才认得出它。

练习 1:把本机端边云跑通(30 分钟)

按第七章做完。验收标准:ESP32 上电后 Node-RED 的 debug 面板持续收到数据,EMQX Dashboard 的 Clients 页能看到esp32-gw01在线。

练习 2:用命令行手动模拟"设备"和"应用"

不开 ESP32,只用两个终端互发。要求:你能说出这一包从"发布者 → Broker → 订阅者"经过哪些环节,并指出 Broker 在里面的作用。

练习 3(故意试错):掐断网络,看数据会不会丢

让 ESP32 正常上报,然后直接关掉电脑 Wi-Fi(或docker stop emqx),等 30 秒再恢复。没有本地队列的话,这 30 秒的数据不见了,而且日志里可能什么都看不出来。然后加一个最简单的队列(哪怕只是内存里的环形数组 + 补传),再试一次。

意义:这是"能演示的 demo"和"能交付的系统"之间的分水岭。

练习 4:改主题结构,体会过滤的威力

先把所有数据都发到agri/data,在 Node-RED 里写过滤逻辑;再改成agri/gw01/up/telemetry的分层结构,用agri/+/up/telemetry订阅。对比两种写法下 Node-RED 流程的复杂度,你就明白为什么要分层。

练习 5(故意试错):把 Broker 地址写错,学会看错误

把.broker.address.uri改成mqtt://192.168.1.999重新烧录,看串口日志里MQTT_EVENT_ERROR的error_type,然后对比两种情况:IP 不存在是传输层(TCP)失败且反复重试;IP 存在但端口没开(如填 1884)是连接被拒,重连间隔由reconnect_timeout_ms决定。

意义:以后遇到"设备离线",你能第一时间分清是"网络不通"还是"Broker 不认我",而不是盲目重启。


小结

  • 端-边-云是三次分工:端接触物理世界,边就地解决本地该解决的事,云负责全局和记忆。
  • 边的价值能折算成钱和可靠性:省带宽(聚合)、省电(重活从电池节点拿走)、断网续传(数据不丢)、本地联动(断网也能控)。每条都能讲出一个具体场景。
  • 协议是分段的:端↔边常常根本不是 IP 网络,边↔云才是 MQTT 的主场。别问"MQTT 和 CoAP 哪个好",要问"这一段用哪个"。
  • 主题设计要趁早:{产品}/{设备}/{方向}/{用途},一用途一主题,动态值进 payload。现在偷懒,以后要还。
  • 下行必须有回报,否则你的系统永远只有开环。

参考:MQTT 3.1.1 / 5.0 协议规范(OASIS);EMQX 官方文档(Docker 部署与 Dashboard 端口);乐鑫 ESP-IDF 编程指南中 esp-mqtt 组件的配置说明。文中协议开销与流量估算为典型值,实际请以抓包(Wireshark)或 Broker 侧统计为准。

下一篇:MQTT 深度实战——QoS、保留消息、遗嘱与订阅树,ESP32 对接 Broker

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询