IoT 整体架构与协议选型
IoT 整体架构
四层架构
物联网系统采用经典的四层架构,自底向上依次为感知层、网络层、平台层和应用层。每层职责清晰,层间通过标准化接口解耦。
┌─────────────────────────────────────────────────────┐
│ 应用层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 智能运营 │ │ 设备监控 │ │ 数据分析 │ │ 告警中心 │ │
│ │ 大屏 │ │ 后台 │ │ 平台 │ │ │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ OTA升级 │ │ 规则编排 │ │ 报表统计 │ │
│ │ 平台 │ │ 引擎 │ │ │ │
│ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────────────┤
│ 平台层 │
│ ┌────────────────────────────────────────────┐ │
│ │ 设备管理服务 │ │
│ │ 注册 / 影子 / 分组 / OTA / 状态管理 │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ 数据接入服务 │ │
│ │ 协议适配 / 消息路由 / 数据解析 / 过滤 │ │
│ └────────────────────────────────────────────┘ │
│ ┌────────────────────────────────────────────┐ │
│ │ 规则引擎 │ │
│ │ 条件触发 / 告警 / 场景联动 / 数据转发 │ │
│ └────────────────────────────────────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 时序数据库 │ │ 关系数据库 │ │ 消息队列 │ │
│ │ (InfluxDB)│ │ (PostgreSQL)│ │ (Kafka) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────────────────────────────┤
│ 网络层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ MQTT │ │ CoAP │ │ HTTP/HTTPS │ │
│ │ Broker │ │ 网关 │ │ API Gateway │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ LoRaWAN │ │ NB-IoT │ │ 4G/5G │ │
│ │ 网关 │ │ 基站 │ │ 蜂窝网络 │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
├─────────────────────────────────────────────────────┤
│ 感知层 │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ 传感器 │ │ 智能终端 │ │ 边缘网关 │ │
│ │(温/湿/压/ │ │ (PLC/DTU) │ │ (协议转换/本地 │ │
│ │ 光/气/磁) │ │ │ │ 处理/缓存) │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────┘各层核心组件与职责
感知层
感知层是物联网系统的神经末梢,负责物理世界数据的采集和指令的执行。
| 组件 | 职责 | 典型设备 |
|---|---|---|
| 传感器 | 采集环境物理量(温度、湿度、压力、光照、气体浓度、磁力等) | 温湿度传感器、PM2.5传感器、红外传感器 |
| 执行器 | 接收指令执行物理动作(开关、调节、告警) | 继电器、电磁阀、步进电机、蜂鸣器 |
| 智能终端 | 具备边缘计算能力的物联网设备,可执行本地逻辑 | PLC、边缘计算盒子、DTU |
| 边缘网关 | 协议转换、数据聚合、本地缓存、断网续传 | 工业网关、家庭智能网关 |
网络层
网络层负责数据传输,提供安全可靠的连接通道。
| 组件 | 职责 | 关键技术 |
|---|---|---|
| 接入网关 | 设备接入认证、协议适配、连接管理 | MQTT Broker、CoAP 网关、HTTP Server |
| 网络传输 | 提供物理层到传输层的网络连接 | TCP/UDP、TLS/DTLS、4G/5G/NB-IoT |
| 边缘节点 | 靠近设备侧的数据处理和转发 | LoRaWAN 网关、5G 基站 |
平台层
平台层是物联网系统的核心,提供设备管理、数据接入、规则引擎和数据存储等核心能力。详见 IoT 平台架构。
应用层
应用层面向最终用户,提供业务功能和人机交互界面。
| 组件 | 职责 |
|---|---|
| 设备监控后台 | 实时设备状态查看、远程控制、日志查询 |
| 智能运营大屏 | 设备分布地图、实时数据仪表盘、KPI 展示 |
| 数据分析平台 | 历史数据查询、趋势分析、异常检测、预测维护 |
| 告警中心 | 告警规则配置、告警通知(短信/邮件/App推送) |
| OTA 升级平台 | 固件版本管理、灰度升级、升级任务调度 |
| 规则编排引擎 | 可视化编排设备联动规则、场景自动化 |
物联网端到端数据流
一条典型的物联网数据从设备采集到应用呈现,经历以下完整链路:
设备端 云端/平台
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 传感器 │────>│ 边缘网关 │────>│ MQTT │────>│ 数据 │
│ │ │(协议转换/ │ │ Broker │ │ 接入服务 │
│ 温度采集 │ │ 数据聚合) │ │ (EMQX) │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
│
▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 应用 │<────│ 规则引擎 │<────│ 数据存储 │
│ 展示 │ │(条件判断/ │ │(时序数据库) │
│ 告警通知 │ │ 场景联动) │ │ │
└──────────┘ └──────────┘ └──────────┘数据流各阶段说明:
- 数据采集:传感器按照设定的采样频率采集物理量,通过 I2C/SPI/UART 等接口传输到设备主控。
- 边缘处理:边缘网关对原始数据进行协议转换(Modbus/MQTT)、数据聚合(去重/均值/滤波)、本地缓存(断网时暂存)。
- 网络传输:网关通过 MQTT 协议将数据发布到 Broker,传输过程中使用 TLS 加密。
- 消息分发:MQTT Broker 根据 Topic 将消息路由到对应的订阅者(数据接入服务)。
- 数据解析:数据接入服务解析 payload(JSON/ProtoBuf/自定义二进制),进行数据清洗和格式转换。
- 规则触发:规则引擎对数据流进行条件匹配,触发告警、联动或其他业务动作。
- 数据存储:时序数据写入时序数据库,事件数据写入消息队列,设备状态同步到影子设备。
- 应用呈现:应用层通过 API 或消息订阅获取数据,展示在仪表盘或触发通知。
IoT 平台架构
设备管理
设备注册
设备注册是设备接入平台的第一步,需完成设备身份信息的录入和凭证分发。
| 注册方式 | 流程 | 适用场景 |
|---|---|---|
| 平台预注册 | 手动录入设备信息(productKey/deviceName/deviceSecret),平台生成凭证 | 量产设备、固定部署场景 |
| 动态注册 | 设备首次上电时携带产品密钥向平台申请身份凭证 | 消费类设备、批量出货 |
| 一型一密 | 同一型号设备共享同一个产品密钥,平台根据设备特征自动分配身份 | 低成本设备、内存受限设备 |
设备注册的核心数据结构:
{
"productKey": "a1B2C3D4",
"deviceName": "sensor_temp_001",
"deviceSecret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"deviceToken": "yyyyyyyyyyyyyyyyyyyyy",
"productModel": "TH-Sensor-Pro-V2",
"firmwareVersion": "1.2.3",
"status": "active",
"registerTime": "2025-06-15T08:00:00Z",
"lastOnlineTime": "2025-06-15T08:30:00Z"
}影子设备
影子设备(Device Shadow)是一种用于缓存设备状态的虚拟设备表示,解决设备离线时应用层无法获取和设置状态的问题。
核心机制:
- 云端状态同步:设备上报状态时同步更新影子文档;应用查询时直接读取影子而非设备本身。
- 期望状态下发:应用层写影子中的 desired 字段,设备在线后同步 desired 到 reported 并执行。
- 离线可操作:设备离线时应用仍可设置期望状态,设备重连后自动同步。
影子文档结构示例:
{
"state": {
"reported": {
"temperature": 25.6,
"humidity": 60.2,
"switch": "on",
"battery": 85
},
"desired": {
"switch": "off",
"targetTemp": 26.0
}
},
"metadata": {
"reported": {
"temperature": { "timestamp": 1718444800000 },
"humidity": { "timestamp": 1718444800000 }
},
"desired": {
"switch": { "timestamp": 1718450000000 }
}
},
"version": 15,
"timestamp": 1718450000000
}固件 OTA
OTA (Over-The-Air) 升级是物联网设备的必备能力,支持远程修复漏洞、更新功能和优化性能。
OTA 升级流程:
升级任务创建 固件分发 设备升级 结果反馈
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ 选择批次 │ │ 固件存储 │ │ 下载固件 │ │ 上报结果 │
│ 配置灰度 │────────>│ (OSS/S3) │────────>│ 校验签名 │────────>│ 升级统计 │
│ 设置策略 │ │ 生成URL │ │ 写入Flash │ │ 异常回滚 │
└────────┘ └────────┘ └────────┘ └────────┘OTA 策略配置项:
| 策略项 | 说明 |
|---|---|
| 灰度比例 | 按百分比逐步放量,如 1% -> 10% -> 50% -> 100% |
| 分批间隔 | 每批次之间等待时间,用于观察升级效果 |
| 升级窗口 | 限定升级执行时间段,如凌晨 2:00-5:00 |
| 最低电量 | 电池设备升级前检查电量,低于阈值禁止升级 |
| 失败回滚 | 升级失败后自动回滚到上一个版本 |
| 签名校验 | 固件包需带 RSA/ECDSA 签名,设备下载后校验完整性 |
设备分组
设备分组用于批量管理和操作,支持多层分组结构:
| 分组类型 | 说明 | 示例 |
|---|---|---|
| 静态分组 | 固定成员设备 | 楼栋A-3层-会议室 |
| 动态分组 | 按条件自动匹配(标签/型号/版本) | firmwareVersion=1.2.x |
| 拓扑分组 | 按物理拓扑关系分组 | 工厂-车间-产线-工位 |
数据接入
协议适配层
协议适配层是平台面对协议异构性的核心抽象层,负责将各种通信协议统一转换为内部标准格式。
┌─────────────────────────────────────┐
│ 协议适配层 │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌────┐ │
MQTT ───────────────────>│ │ MQTT │ │ CoAP │ │ HTTP │ │自定义│ │
CoAP ───────────────────>│ │ 适配器 │ │ 适配器 │ │ 适配器 │ │适配器│ │
HTTP ───────────────────>│ └──────┘ └──────┘ └──────┘ └────┘ │
LoRaWAN ────────────────>│ │ │ │ │
Modbus ─────────────────>│ ▼ ▼ ▼ │
OPC-UA ────────────────>│ ┌──────────────────────┐ │
│ │ 统一消息模型 │ │
│ │ (标准Topic + 标准Payload) │ │
│ └──────────────────────┘ │
└─────────────────────────────────────┘
│
▼
┌──────────────────────┐
│ 消息路由层 │
└──────────────────────┘适配器需要处理的核心差异:
| 维度 | MQTT 适配器 | CoAP 适配器 | HTTP 适配器 |
|---|---|---|---|
| 传输层 | TCP/TLS | UDP/DTLS | TCP/TLS |
| 通信模型 | 发布/订阅 | 请求/响应(支持 Observe) | 请求/响应 |
| 消息标识 | Topic | URL Path | URL Path |
| payload 编码 | 透传 | 透传 | 透传 |
| 鉴权方式 | Username/Password + ClientID | Pre-Shared Key | Bearer Token |
消息路由
消息路由负责将设备消息按规则分发到不同的数据处理器。
路由策略:
- 基于 Topic 路由:设备消息的 Topic 包含产品、设备、功能点等信息,路由层按 Topic 模式匹配分发。例如
/prod/a1B2C3D4/sensor_temp_001/property/temperature路由到时序存储处理器。 - 基于内容路由:解析 payload 中的字段值,根据值范围或条件分发。例如温度超过 50 度时路由到告警处理器。
- 基于设备属性路由:根据设备的型号、分组、租户等属性分发。例如不同租户的消息路由到不同的数据处理管道。
数据解析
设备上传的数据格式各异,平台需提供灵活的数据解析能力:
| 数据格式 | 适用场景 | 解析方式 |
|---|---|---|
| JSON | 智能家居、消费类 IoT | 标准 JSON 解析,Schema 校验 |
| ProtoBuf | 低带宽、高吞吐场景 | 预定义 .proto 文件,代码生成解析器 |
| TLV 编码 | 内存受限的嵌入式设备 | 按协议规范逐字节解析 |
| 自定义二进制 | 工业协议(Modbus/Profibus) | Script Engine(JavaScript/Lua)实现脚本解析 |
规则引擎
规则引擎是 IoT 平台实现自动化和智能化的核心组件,采用 ECA(Event-Condition-Action)模型。
┌────────────────────────────┐
│ 事件源 │
│ 设备属性上报 / 事件上报 / │
│ 设备上下线 / 定时器 │
└────────────┬───────────────┘
│
▼
┌────────────────────────────┐
│ 条件判断 │
│ > 阈值 / == 状态 / IN 集合 / │
│ AND/OR/NOT 复合 / 窗口聚合 │
└────────────┬───────────────┘
│ (匹配)
▼
┌────────────────────────────┐
│ 动作执行 │
│ 设备控制 / HTTP 回调 / 消息推送 │
│ / 场景联动 / 数据持久化 / 写影子 │
└────────────────────────────┘条件触发类型
| 触发类型 | 说明 | 示例 |
|---|---|---|
| 属性触发 | 设备属性上报时触发 | 温度 > 40 度触发告警 |
| 事件触发 | 设备事件上报时触发 | 设备故障事件触发维修工单 |
| 生命周期触发 | 设备上下线、注册时触发 | 设备离线超过 10 分钟触发通知 |
| 定时触发 | 按 Cron 表达式定时执行 | 每天 8:00 开启灌溉系统 |
| 联动触发 | 多个条件组合触发 | 温度 > 30 度且湿度 < 40% 时开启加湿器 |
告警规则
告警规则可按严重级别和通知方式配置:
| 级别 | 说明 | 通知方式 |
|---|---|---|
| 严重 | 设备故障、数据异常,需立即处理 | 短信 + 电话 + App 推送 |
| 警告 | 数据超出阈值,需关注 | 邮件 + App 推送 |
| 提示 | 信息性通知 | App 推送、日志记录 |
场景联动
场景联动是指多个设备和规则按照特定逻辑协同工作。例如:
智能温室场景:
触发条件: 温度 > 35 度 且 光照 > 80000 lux
动作:
1. 开启遮阳帘 (继电器)
2. 开启排风扇 (变频器 -> 1000 RPM)
3. 开启喷雾系统 (电磁阀 -> 开启 30 秒)
4. 发送通知到管理后台数据存储
时序数据库选型
物联网产生的数据以时间序列为主,时序数据库是 IoT 平台的核心存储组件。以下是三种主流时序数据库的对比分析。
| 特性 | InfluxDB (v2.x) | TDengine | TimescaleDB |
|---|---|---|---|
| 架构 | 单机/集群(闭源) | 集群原生(开源) | PostgreSQL 插件 |
| 数据模型 | Measurement + Tag + Field | 超级表 + 子表 | Hypertable + Chunk |
| 写入性能 | ~100万 points/秒 | ~1000万 points/秒 | ~50万 points/秒 |
| 压缩率 | ~10x | ~20x | ~5x |
| SQL 兼容 | Flux/InfluxQL | SQL(MySQL 兼容) | SQL(PostgreSQL 兼容) |
| 集群部署 | 企业版支持 | 原生支持 | 依赖 PG 扩展 |
| 流式计算 | Task 脚本 | 内置流式计算 | 借助 PG 触发器 |
| 数据保留策略 | Retention Policy + Bucket | 自动过期删除 | 数据保留策略 + 压缩 |
| 可视化 | 内置 UI | Grafana 插件 | Grafana 原生 |
| 开源协议 | MIT(单机) | AGPL | Timescale License |
选型建议:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 中小规模 (< 10万设备) | InfluxDB OSS | 部署简单,社区活跃,内置 UI |
| 大规模 (> 10万设备) | TDengine | 极高写入性能、原生集群、优秀压缩率 |
| 已有 PostgreSQL 技术栈 | TimescaleDB | SQL 生态兼容,易于与业务系统集成 |
| 工业 IoT (高频率采样) | TDengine | 写入吞吐量最高,针对物联网场景深度优化 |
数据分层存储策略
物联网数据具备明显的时间衰减特性,宜采用分层存储策略以平衡成本和查询性能。
| 存储层 | 时间范围 | 存储介质 | 数据精度 | 用途 |
|---|---|---|---|---|
| 热存储 | 最近 7 天 | 内存 / NVMe SSD | 原始精度 | 实时监控、最近查询 |
| 温存储 | 7 天 ~ 3 个月 | SSD / HDD | 原始精度 | 近期分析、报表 |
| 冷存储 | 3 个月 ~ 1 年 | HDD / 对象存储 | 聚合降采样 | 月报、合规审计 |
| 归档 | 1 年以上 | 对象存储 (OSS/S3) | 月度聚合 | 长期归档 |
通信协议选型
MQTT
MQTT (Message Queuing Telemetry Transport) 是物联网领域应用最广泛的通信协议,基于发布/订阅模式设计,协议轻量、带宽占用低。
核心特性
发布/订阅模型
MQTT 采用发布/订阅模式,解耦消息的生产者和消费者。设备发布消息到 Topic,订阅者接收消息,消息的流转完全由 Broker 管理。
┌──────────────────────────────────────┐
│ MQTT Broker │
│ ┌──────────┐ │
│ │ 消息路由 │ │
│ │ Topic → │────> 订阅者 A (温度面板) │
│ │ Subscriber│────> 订阅者 B (告警服务) │
│ └──────────┘────> 订阅者 C (持久化服务) │
│ ▲ │
└────────┼──────────────────────────────┘
│
┌─────┴─────┐
│ 发布者 │
│ (温度传感器) │
└───────────┘Topic 设计规范示例:
/product/{productKey}/device/{deviceName}/property/{propertyName}
/product/{productKey}/device/{deviceName}/event/{eventType}
/product/{productKey}/device/{deviceName}/command/{commandName}
/sys/{productKey}/{deviceName}/ota/upgrade
/sys/{productKey}/{deviceName}/shadow/updateQoS 级别
MQTT 定义了三个 QoS(Quality of Service)级别,用于控制消息投递的可靠性。
| QoS 级别 | 语义 | 发送次数 | 确认机制 | 适用场景 |
|---|---|---|---|---|
| 0 (至多一次) | Fire and Forget | 1 次 | 无确认 | 高频传感器数据(允许丢少数点) |
| 1 (至少一次) | 保证送达,可能重复 | 1 次以上 | PUBACK | 设备状态上报(幂等场景) |
| 2 (恰好一次) | 保证送达且不重复 | 2 次往返 | PUBREC/PUBREL/PUBCOMP | 控制指令、设备配置下发 |
实际部署中,QoS 1 是最常用的折中选择,QoS 2 因性能开销大仅在关键指令中使用。
遗嘱消息
遗嘱消息(Will Message)是 MQTT 协议的重要特性,用于在设备异常断开时通知其他订阅者。
机制:设备在 CONNECT 时设置遗嘱 Topic 和遗嘱消息。当 Broker 检测到设备异常断开(网络中断、设备掉电)时,代表设备发布遗嘱消息。
典型用途:
- 设备上下线状态检测
- 分布式系统中的节点健康监控
- 网关子设备的离线通知
保留消息
保留消息(Retained Message)让 Broker 为每个 Topic 保留最后一条消息。新订阅者订阅时立即收到保留消息,无需等待设备下一次发布。
用途:
- 设备最新状态快速获取(替代部分影子设备功能)
- 系统配置的持久化广播
- 传感器最新读数展示
MQTT 使用场景
| 场景 | 推荐度 | 原因 |
|---|---|---|
| 智能家居 | 强烈推荐 | 双向通信,低功耗,适合大量设备 |
| 工业监控 | 强烈推荐 | 稳定可靠,QoS 保证,大量传感器 |
| 车联网 | 强烈推荐 | 连接不稳定场景,遗嘱消息检测离线 |
| 消费类 App Push | 推荐 | 长连接保持,省电 |
| 高频率遥测 | 推荐 | QoS 0 场景下协议开销极低 |
CoAP
CoAP (Constrained Application Protocol) 专为受限设备设计,基于 UDP 传输,采用类 RESTful 的资源模型。
核心特性
- RESTful 模型:使用 GET/POST/PUT/DELETE 方法操作资源,类似 HTTP 但面向物联网优化。
- UDP 传输:协议头仅 4 字节,比 MQTT 更轻量,适合内存和功耗极度受限的设备。
- 资源发现:通过
/.well-known/core路径发布资源列表,支持设备自动发现和注册。 - Observe 模式:客户端注册资源观察后,资源变化时服务器主动推送,类似 MQTT 的订阅机制。
- 消息确认:提供 CON(可靠)和 NON(不可靠)两种消息类型,类似 MQTT 的 QoS 0/1。
CoAP 与 HTTP 对比
| 特性 | CoAP | HTTP |
|---|---|---|
| 传输层 | UDP | TCP |
| 协议头大小 | 4 字节 | 通常 > 200 字节 |
| 消息模型 | 异步(CON/NON) | 同步请求/响应 |
| 资源发现 | 内置 (Core Link Format) | 需额外 API |
| 适用硬件 | 8-bit MCU, 几十 KB RAM | 有足够计算和内存资源 |
使用场景
- 资源严重受限的传感器节点(8 位 MCU、几十 KB 内存)
- 低功耗无线传感网络(6LoWPAN)
- 楼宇自动化中的灯光控制、HVAC 系统
HTTP/HTTPS
HTTP/HTTPS 是最通用的协议,但在物联网场景中适用面较窄,主要用于高带宽、非实时性场景。
适用场景
- 固件下载:OTA 升级包较大,HTTP 分块下载 + 断点续传是最优方案。
- 设备配置:设备初始化时从云端拉取配置信息。
- 数据上报(非实时):非关键数据定时批量上报,如日度日志。
- API 管理:平台层内部服务间通信和对外 RESTful API。
限制
- 协议头开销大,不适合低带宽和按流量计费的 NB-IoT 场景。
- 请求/响应模型无法支持服务端主动推送(需配合 WebSocket 或长轮询)。
- 相比 MQTT,HTTP 在高并发连接场景下资源占用更高。
LwM2M
LwM2M (Lightweight Machine-to-Machine) 由 OMA SpecWorks 定义,基于 CoAP 构建,提供完整的设备管理框架。
对象资源模型
LwM2M 的核心是对象-资源模型:
LwM2M 设备
├── 对象 0 (安全对象) — 安全凭证存储
├── 对象 1 (服务器对象) — 服务器连接配置
├── 对象 2 (访问控制对象) — ACL 权限控制
├── 对象 3 (设备对象) — 设备信息(制造商/型号/固件版本)
├── 对象 4 (连接监控对象) — 网络连接统计
├── 对象 5 (固件更新对象) — OTA 升级管理
├── 对象 6 (位置对象) — GPS 坐标
└── 自定义对象 — 行业特定数据模型每个对象包含多个资源(Resource),资源是具体的数据项或操作。
LwM2M 接口
| 接口 | 功能 | 操作 |
|---|---|---|
| Bootstrap | 设备初始配置 | 写入 Access Token、服务器地址 |
| Device Discovery & Registration | 设备注册与发现 | Register/Update/Deregister |
| Device Management & Service Enablement | 设备管理与控制 | Read/Write/Execute/Create/Delete |
| Information Reporting | 数据上报与通知 | Observe/Notify/Cancel Observation |
使用场景
- 运营商级 IoT 平台(如 OneM2M 兼容平台)
- 需要标准化设备管理的工业场景
- 芯片级集成(如 NB-IoT 模组内置 LwM2M 协议栈)
LoRaWAN / NB-IoT
LoraWAN 和 NB-IoT 属于 LPWAN(Low Power Wide Area Network)技术,专为远距离、低功耗、小数据量的物联网场景设计。
| 特性 | LoRaWAN | NB-IoT |
|---|---|---|
| 频段 | Sub-1GHz (ISM 免许可) | 授权蜂窝频段 |
| 通信距离 | 2-15 km (视环境) | 1-10 km (蜂窝基站覆盖) |
| 数据速率 | 0.3-50 kbps | 20-250 kbps |
| 功耗 | 极低(电池寿命 5-10 年) | 低(电池寿命 3-5 年) |
| 延迟 | 高(非实时) | 中等(秒级) |
| 部署方式 | 自建网关 | 运营商基站 |
| 设备成本 | 极低 | 低 |
| 网络覆盖 | 需自建 | 运营商覆盖 |
典型应用
| 场景 | 推荐技术 | 原因 |
|---|---|---|
| 智能水表/气表 | LoRaWAN / NB-IoT | 每天上报一次,数据量极小,电池寿命要求 5 年以上 |
| 市政路灯控制 | LoRaWAN | 自建网络,控制权自主 |
| 智能停车 | NB-IoT | 利用运营商现网覆盖,无需自建网关 |
| 环境监测 | LoRaWAN | 偏远地区无蜂窝信号,LoRaWAN 覆盖距离远 |
| 资产追踪 | NB-IoT | 需要移动性支持,蜂窝网络天然支持 |
协议对比表
| 维度 | MQTT | CoAP | HTTP/HTTPS | LwM2M | LoRaWAN | NB-IoT |
|---|---|---|---|---|---|---|
| 传输层 | TCP/TLS | UDP/DTLS | TCP/TLS | UDP/DTLS (基于CoAP) | 自定义 LoRa 协议 | LTE (蜂窝) |
| 通信模型 | 发布/订阅 | 请求/响应 + Observe | 请求/响应 | 发布/订阅 + 请求/响应 | 星型 (设备->网关) | 星型 (设备->基站) |
| 协议头大小 | 2 字节 (最小) | 4 字节 | 200+ 字节 | 4+ 字节 | 极小 | 极小 |
| 功耗 | 中 (需保持长连接) | 低 (无连接) | 高 (TCP 连接) | 低 | 极低 | 低 |
| 带宽占用 | 低 | 极低 | 高 | 极低 | 极低 (< 50 kbps) | 低 (< 250 kbps) |
| QoS 保证 | 3 级 (0/1/2) | 2 级 (CON/NON) | 无 (应用层实现) | 2 级 | 无 (ALOHA) | 有 (蜂窝可靠性) |
| 双向通信 | 是 | 是 (Observe) | 仅轮询 | 是 | 下行受限 | 是 |
| 设备发现 | 无 | 有 (资源发现) | 无 | 有 (注册接口) | 有 (Join Server) | 有 (HSS) |
| 安全性 | TLS + ACL | DTLS + PSK | TLS | DTLS + 安全对象 | AES-128 双层加密 | 3GPP 安全 |
| 管理能力 | 无 (需扩展) | 无 | 无 | 完整设备管理 | 有限 (MAC 层) | 有限 |
| 推荐场景 | 通用 IoT, 车联网, 智能家居 | 受限设备, 6LoWPAN | 固件下载, API | 运营商平台, 工业 | 低功耗远距离传感 | 蜂窝覆盖的计量类 |
| 典型部署 | Broker 集群 | CoAP 网关 | API Gateway | LwM2M Server | LoRaWAN NS | 运营商核心网 |
MQTT Broker 部署
Mosquitto / EMQX / VerneMQ 对比
| 特性 | Mosquitto | EMQX | VerneMQ |
|---|---|---|---|
| 开发语言 | C | Erlang/OTP | Erlang/OTP |
| 许可证 | EPL-2.0 (开源) | Apache 2.0 | Apache 2.0 |
| 单节点连接数 | ~10万 | ~100万 | ~50万 |
| 消息吞吐 | ~10万 msg/s | ~500万 msg/s | ~100万 msg/s |
| 集群模式 | 桥接(手动配置) | 原生分布式集群 | 原生分布式集群 |
| MQTT 5.0 | 支持 | 支持 | 支持 |
| 规则引擎 | 无 | 内置 SQL 规则引擎 | 内置 |
| WebHook | 有限(插件) | 内置 | 内置 |
| 共享订阅 | 有限 | 内置 | 内置 |
| 桥接模式 | 支持 | 支持 | 支持 |
| 认证授权 | 支持多种后端 | 内置 + 外部扩展 | 内置 + 外部扩展 |
| 管理 UI | 无(第三方) | Dashboard (完整) | 有(基础) |
| 插件/扩展 | 插件机制 | 插件系统 + ExHook | 插件系统 |
| 运维复杂度 | 低 | 中 | 中 |
| 适用规模 | 中小型(< 1万设备) | 大型(10万-1000万设备) | 大型(10万-500万设备) |
选型建议:
- Mosquitto:简单场景,开发环境,边缘网关本地 Broker。
- EMQX:生产环境首选,高性能、高可用需求,需要规则引擎和数据集成。
- VerneMQ:需要原生多数据中心复制能力,对 MQTT 5.0 有深度需求。
EMQX 集群搭建
架构设计
推荐生产架构:
┌─────────────────────────────┐
│ 负载均衡层 │
│ Nginx / HAProxy / LB │
│ (TCP 负载均衡) │
└──────────┬──────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ EMQX Node 1 │◄──────►│ EMQX Node 2 │◄──────►│ EMQX Node 3 │
│ (Core) │ │ (Core) │ │ (Core) │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
▼
┌────────────────────────────┐
│ 集群互联 (Erlang) │
│ 发现方式: etcd / DNS / K8s │
└────────────────────────────┘配置文件核心参数
# EMQX 集群配置 (emqx.conf)
node:
name: emqx@192.168.1.10
cookie: "EMQX_CLUSTER_SECRET_COOKIE"
cluster:
name: iot_cluster
discovery_strategy: etcd
etcd:
server: "http://192.168.1.100:2379"
prefix: emqx/
node_ttl: 30
listeners:
tcp:
default:
bind: "0.0.0.0:1883"
max_connections: 1000000
ssl:
default:
bind: "0.0.0.0:8883"
max_connections: 100000
keyfile: "/etc/emqx/certs/server.key"
certfile: "/etc/emqx/certs/server.crt"
authorization:
sources:
- type: http
enable: true
url: "http://auth-service:8080/auth"
headers:
content-type: application/json
body:
username: "${username}"
password: "${password}"
clientid: "${clientid}"
retainer:
enable: true
max_payload_size: 1024KB
expiry_interval: 0Docker Compose 部署示例
version: '3.8'
services:
emqx1:
image: emqx/emqx:5.8.0
environment:
- EMQX_NODE_NAME=emqx@192.168.1.10
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_CLUSTER__STATIC__SEEDS=[emqx@192.168.1.10,emqx@192.168.1.11,emqx@192.168.1.12]
volumes:
- emqx1-data:/opt/emqx/data
- emqx1-log:/opt/emqx/log
- ./certs:/opt/emqx/certs
ports:
- "1883:1883"
- "8883:8883"
- "8081:8081"
- "18083:18083"
networks:
- iot-net
emqx2:
image: emqx/emqx:5.8.0
environment:
- EMQX_NODE_NAME=emqx@192.168.1.11
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_CLUSTER__STATIC__SEEDS=[emqx@192.168.1.10,emqx@192.168.1.11,emqx@192.168.1.12]
volumes:
- emqx2-data:/opt/emqx/data
- emqx2-log:/opt/emqx/log
- ./certs:/opt/emqx/certs
networks:
- iot-net
emqx3:
image: emqx/emqx:5.8.0
environment:
- EMQX_NODE_NAME=emqx@192.168.1.12
- EMQX_CLUSTER__DISCOVERY_STRATEGY=static
- EMQX_CLUSTER__STATIC__SEEDS=[emqx@192.168.1.10,emqx@192.168.1.11,emqx@192.168.1.12]
volumes:
- emqx3-data:/opt/emqx/data
- emqx3-log:/opt/emqx/log
- ./certs:/opt/emqx/certs
networks:
- iot-net
haproxy:
image: haproxy:2.8
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
ports:
- "1883:1883"
- "8883:8883"
depends_on:
- emqx1
- emqx2
- emqx3
networks:
- iot-net
networks:
iot-net:
driver: bridge
volumes:
emqx1-data:
emqx2-data:
emqx3-data:
emqx1-log:
emqx2-log:
emqx3-log:共享订阅
共享订阅是 MQTT 5.0 引入的负载均衡机制,允许同一组订阅者共享消息的分发,实现负载均衡和高可用。
无共享订阅: 共享订阅 ($share/g1/topic):
Client A ──sub topic/T ──> │ │ Client A ──sub $share/g1/topic/T ──> │ │
│ Broker │ Client B ──sub $share/g1/topic/T ──> │ Broker │
Client B ──sub topic/T ──> │ │ Client C ──sub $share/g1/topic/T ──> │ │
└──────────────┘ └──────────────┘
消息到达 topic/T 时: 消息到达 topic/T 时:
Client A 和 Client B 都收到 Client A / B / C 中仅一个收到
(广播模式) (负载均衡模式)共享订阅支持多种分发策略:
| 策略 | 说明 |
|---|---|
| random | 随机选择一个订阅者 |
| round_robin | 轮询分配给订阅者 |
| sticky | 同一来源的消息固定发到同一订阅者 |
| hash | 按 ClientID 哈希分配 |
桥接模式
桥接(Bridge)用于将两个或多个 MQTT Broker 连接起来,实现跨区域、跨网络的消息同步。
┌──────────────┐ ┌──────────────┐
│ EMQX 集群A │────桥接──────>│ EMQX 集群B │
│ (上海数据中心) │<──桥接返回────│ (北京数据中心) │
└──────────────┘ └──────────────┘
│ │
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ 华东设备 │ │ 华北设备 │
└───────────┘ └───────────┘桥接配置要点:
- Topic 过滤:仅转发匹配指定模式的消息,避免跨区流量过大。
- 单向/双向:可配置为单向转发(边缘->中心)或双向同步。
- 缓存转发:桥接中断时本地缓存消息,恢复后自动转发。
- QoS 映射:桥接链路可根据需要调整 QoS 级别。
规则引擎与 WebHook
EMQX 内置的规则引擎可对设备消息进行 SQL 风格的过滤、转换和转发。
SQL 规则示例
-- 温度超过阈值时转发到告警服务
SELECT
clientid,
payload.temperature as temp,
payload.humidity as hum,
timestamp
FROM
"devices/+/property/temperature"
WHERE
payload.temperature > 45
AND payload.temperature < 150-- 将所有设备属性数据持久化到时序数据库
SELECT
clientid as device_id,
payload.*,
timestamp as ts
FROM
"devices/+/property/+"
INTO
"influxdb://iot_db/device_metrics"WebHook 配置
EMQX WebHook 可以将设备事件以 HTTP 回调的方式推送到业务系统:
webhook:
url: "http://webhook-service:8080/emqx/webhook"
headers:
Authorization: "Bearer ${EMQX_WEBHOOK_TOKEN}"
retry_interval: 5s
max_retry_times: 3
events:
- client.connect
- client.disconnect
- session.subscribed
- session.unsubscribed
- message.publish
- message.deliver
- message.ackedWebHook 事件类型及用途:
| 事件类型 | 触发时机 | 典型使用场景 |
|---|---|---|
| client.connect | 设备连接时 | 设备认证、连接计数 |
| client.disconnect | 设备断开时 | 离线状态更新 |
| session.subscribed | 订阅 Topic 时 | 订阅审计 |
| message.publish | 消息发布时 | 数据持久化、规则匹配 |
| message.deliver | 消息投递时 | 投递追踪 |
| message.acked | 消息确认时 | QoS 1/2 消息确认追踪 |
IoT 安全
设备身份认证
设备接入平台时必须通过身份认证,防止非授权设备接入。常用的认证方案有:
一机一密
每台设备在出厂时烧录唯一的 ProductKey、DeviceName 和 DeviceSecret,设备连接时使用这些凭证进行签名认证。
认证流程:
设备 平台
│ │
│──── CONNECT ──────────────────>│
│ username: deviceName │
│ password: HMAC-MD5(deviceSecret, timestamp)│
│ clientId: productKey&deviceName×tamp│
│ │
│<─── CONNACK (success/fail) ────│
│ 或 │
│<─── 强制断开 (认证失败) ────────│签名计算方式:
clientId = productKey + "&" + deviceName + "&" + timestamp
password = HMAC_SHA256(deviceSecret, clientId)双向 TLS
使用 X.509 证书进行双向认证,设备端和服务端各自持有证书,建立 TLS 连接时相互验证。
设备 (证书 A) 平台 (证书 B)
│ │
│──── ClientHello ─────────────>│
│ │
│<─── ServerHello + Cert(B) ────│
│ │
│──── Client Cert(A) ──────────>│ <-- 平台验证设备证书
│ │
│──── Verify ─────────────────>│
│ │
│<─── Finished ────────────────│
│ │
│──── MQTT CONNECT ───────────>│
│<─── CONNACK ─────────────────│双向 TLS 的优缺点:
| 优点 | 缺点 |
|---|---|
| 安全性最高,防重放、防伪造 | 证书管理复杂,需维护 CA 和证书生命周期 |
| 出厂预置证书,无需网络分发密钥 | 证书存储需要安全硬件(SE/TEE) |
| 天然防中间人攻击 | 设备端证书更新困难 |
选型建议:消费级 IoT(智能家居)使用一机一密即可;工业 IoT、车联网等对安全要求高的场景推荐双向 TLS。
传输加密
| 协议 | 加密层 | 适用传输层 | 推荐强度 | 说明 |
|---|---|---|---|---|
| TLS 1.3 | 传输层 | TCP | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | MQTT over TLS (8883)、HTTPS |
| DTLS 1.3 | 传输层 | UDP | TLS_AES_128_GCM_SHA256 | CoAP over DTLS (5684) |
| AES-128 | 应用层 | 任意 | AES-128-CCM | LoRaWAN 空口加密 |
| PSK | 应用层 | 任意 | 预共享密钥 | LwM2M Bootstrap 阶段 |
最小安全要求:
- 使用 TLS 1.2 及以上版本,禁用 TLS 1.0/1.1 和 SSL 全系列。
- 选择 ECDHE 密钥交换算法,禁用 RSA 密钥交换。
- 证书应使用不小于 256 位的 ECDSA 密钥或 2048 位的 RSA 密钥。
- 定期轮换证书和密钥,建议证书有效期不超过 2 年。
固件签名校验
固件签名校验是防止固件被篡改和植入恶意代码的关键安全措施。
固件发布流程:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 固件构建 │────>│ 签名操作 │────>│ 固件发布 │
│ (编译/打包) │ │ (RSA-256) │ │ (上传云存储) │
└──────────┘ └──────────┘ └──────────┘
│ │
│ 私钥 (安全存储) │ 公钥 (预置在设备)
▼ ▼
┌──────────┐ ┌──────────┐
│ 签名生成 │ │ 固件验证 │
│ Sign(FW) │ │ Verify(签名)│
└──────────┘ └──────────┘
设备端校验流程:
1. 下载固件包(含签名和固件数据)
2. 读取固件头部的签名数据
3. 使用预置的公钥验证签名
4. 签名验证通过 → 校验固件哈希 → 写入 Flash
5. 签名验证失败 → 丢弃固件 → 上报升级失败事件安全要点:
- 签名密钥对在安全的 HSM(硬件安全模块)中生成和使用,私钥永不离开 HSM。
- 设备端使用安全启动(Secure Boot),确保 bootloader 验证固件签名。
- 固件包中包含版本号,防止版本回滚攻击(Downgrade Attack)。
- 升级过程中掉电应能恢复至升级前的版本。
访问控制与权限管理
IoT 平台的访问控制采用 RBAC(Role-Based Access Control)模型,覆盖设备、应用和用户三级权限。
设备级权限
通过 MQTT ACL(Access Control List)控制设备可操作的 Topic:
| 设备 | 允许 Publish 的 Topic | 允许 Subscribe 的 Topic |
|---|---|---|
| 温度传感器 A | /prod/pKeyA/deviceA/property/temperature | /prod/pKeyA/deviceA/command/# |
| 智能开关 B | /prod/pKeyB/deviceB/property/switch | /prod/pKeyB/deviceB/command/set |
| 通用规则 | 仅允许操作自身产品下的 Topic | 仅允许订阅自身的命令 Topic |
ACL 规则引擎配置示例:
authorization:
sources:
- type: built_in_database
rules:
- username: sensor_001
publish: ["/prod/pKeyA/sensor_001/#"]
subscribe: ["/prod/pKeyA/sensor_001/command/#"]
deny_publish: ["#"]
- username: actuator_002
publish: ["/prod/pKeyB/actuator_002/property/#"]
subscribe: ["/prod/pKeyB/actuator_002/command/#"]应用级权限
应用和 API 的权限管理通过 OAuth 2.0 + RBAC 实现:
| 角色 | 权限范围 | 可操作资源 |
|---|---|---|
| 超级管理员 | 全平台管理 | 所有设备、所有用户、系统配置 |
| 租户管理员 | 租户内管理 | 租户下设备、租户下用户、租户配置 |
| 设备运维 | 设备操作 | 查看设备、远程控制、OTA 升级 |
| 数据查看 | 只读 | 设备数据查询、报表查看 |
| 告警处理 | 告警操作 | 查看和确认告警 |
最小权限原则实施要点
- Topic 隔离:设备 Topic 按产品和设备维度隔离,设备只能访问自身范围内的 Topic。
- API 鉴权:平台 API 使用 JWT Token 鉴权,Token 中携带角色和权限 scope。
- 数据隔离:多租户场景下,设备数据按租户维度做物理或逻辑隔离。
- 操作审计:所有敏感操作(OTA、远程控制、配置修改)记录审计日志。
- 临时凭证:设备临时操作使用 STS(临时安全凭证),过期自动失效。