第3章 MQTT核心概念详解

第3章 MQTT核心概念详解

3.1 发布/订阅模式

模式对比

MQTT发布-订阅模式
消息
消息
转发
转发
转发
发布者
Broker
发布者
订阅者1
订阅者2
订阅者3
传统客户端-服务器模式
请求
请求
请求
响应
响应
响应
客户端1
服务器
客户端2
客户端3

发布/订阅工作流程

订阅者B 订阅者A Mosquitto Broker 发布者 订阅者B 订阅者A Mosquitto Broker 发布者 1. 订阅主题 2. 发布消息 3. 发布者与订阅者 完全解耦 SUBSCRIBE home/temperature QoS: 1 SUBACK QoS授予: 1 SUBSCRIBE home/ SUBACK QoS授予: 2 PUBLISH home/temperature QoS: 1 Payload: "25°C" PUBLISH home/temperature QoS: 1 Payload: "25°C" PUBLISH home/temperature QoS: 2 Payload: "25°C"

发布/订阅的优势

特性 传统模式 发布/订阅模式
耦合性 紧耦合(客户端需知道服务器地址) 松耦合(发布者无需知道订阅者)
扩展性 受限于服务器处理能力 通过Broker轻松扩展
灵活性 需要修改代码添加新客户端 动态订阅即可
网络拓扑 点对点 多对多
时间耦合 同步通信 异步通信

消息流转过程



QoS 0
QoS 1
QoS 2
发布者发送消息
建立TCP连接
PUBLISH报文
Mosquitto Broker
主题匹配
有匹配订阅?
消息入队
丢弃消息
QoS等级?
发送一次

不确认
发送后等待

PUBACK
完整握手

PUBREC/PUBREL/PUBCOMP
完成

3.2 主题(Topic)详解

主题命名规范

主题命名规范
基本规则
大小写敏感
推荐
不能包含空格
UTF-8编码
层级设计
从大到小
语义清晰
层级适中
避免过深
命名建议
使用小写
连词符-分隔
避免特殊字符
保留前缀$

主题层级示例

复制代码
智能家居主题树:
home/                      # 根主题
├── livingroom/            # 客厅
│   ├── temperature        # 温度
│   ├── humidity           # 湿度
│   ├── light              # 灯光
│   └── aircon             # 空调
├── bedroom/               # 卧室
│   ├── temperature
│   ├── light
│   └── curtain            # 窗帘
├── kitchen/               # 厨房
│   ├── temperature
│   ├── smoke              # 烟雾
│   └── door               # 门磁
└── gateway/               # 网关
    ├── status
    └── connectivity

通配符使用

通配符类型

  • 单级通配符

多级通配符

home/+/temperature
sensor/+/data
device/+/status
home/#
sensor/floor1/#

匹配:

home/livingroom/temperature

home/bedroom/temperature
不匹配:

home/livingroom/temperature/detail
匹配:

home/

home/livingroom

home/livingroom/temperature

通配符使用规则

通配符 位置 匹配规则 示例 匹配 不匹配
+ 任意 单个层级 home/+/temp home/livingroom/temp home/livingroom/temp/detail
# 末尾 多个层级 home/# home, home/a, home/a/b hometest

使用示例:

bash 复制代码
# 订阅所有温度传感器
mosquitto_sub -v -t "home/+/temperature"

# 订阅客厅所有设备
mosquitto_sub -v -t "home/livingroom/#"

# 订阅所有楼层状态
mosquitto_sub -v -t "building/+/status"

# 订阅所有消息(谨慎使用)
mosquitto_sub -v -t "#"

系统保留主题

保留主题 SYS - 系统信息
share - 共享订阅 SYS/broker/version
SYS/broker/clients/connected SYS/broker/load/messages/...
$share/group1/topic

$SYS 主题示例:

bash 复制代码
# 查看所有系统主题
mosquitto_sub -v -t "$SYS/#"

# 常用系统主题
$SYS/broker/version                    # Broker版本
$SYS/broker/uptime                     # 运行时间
$SYS/broker/timestamp                  # 时间戳
$SYS/broker/clients/connected          # 连接的客户端数
$SYS/broker/clients/disconnected       # 断开的客户端数
$SYS/broker/messages/received          # 接收的消息数
$SYS/broker/messages/sent              # 发送的消息数
$SYS/broker/bytes/received             # 接收的字节数
$SYS/broker/bytes/sent                 # 发送的字节数

3.3 QoS质量等级

QoS等级概览

QoS等级
QoS 0 - 最多一次
QoS 1 - 至少一次
QoS 2 - 恰好一次
🚀 性能最优
⚠️ 可能丢失
📡 适合不重要数据
✅ 保证送达
⚠️ 可能重复
📡 平衡性能
✅✅ 保证送达
✅✅ 不重复
🐌 性能开销大

QoS工作流程对比

订阅者 Broker 发布者 订阅者 Broker 发布者 QoS 0 - 最多一次 不需要确认,可能丢失 QoS 1 - 至少一次 需要确认,可能重复 QoS 2 - 恰好一次 四次握手,保证不重复 PUBLISH (QoS 0) PUBLISH (QoS 0) PUBLISH (QoS 1, PacketId=1) PUBACK (PacketId=1) PUBLISH (QoS 1, PacketId=2) PUBACK (PacketId=2) PUBLISH (QoS 2, PacketId=3) PUBREC (PacketId=3) PUBREL (PacketId=3) PUBCOMP (PacketId=3) PUBLISH (QoS 2, PacketId=4) PUBREC (PacketId=4) PUBREL (PacketId=4) PUBCOMP (PacketId=4)

QoS决策流程

不重要
重要


需要发送消息
数据重要性?
QoS 0

最多一次
需要严格

不重复?
QoS 2

恰好一次
QoS 1

至少一次
示例:

温度传感器

心跳检测

实时位置
示例:

告警消息

控制指令

配置更新
示例:

计费数据

金融交易

关键日志
选择完成

QoS使用示例

bash 复制代码
# QoS 0 - 最多一次(性能最高)
mosquitto_pub -t "sensor/temperature" -m "25.5" -q 0

# QoS 1 - 至少一次(推荐)
mosquitto_pub -t "alert/fire" -m "Fire detected!" -q 1

# QoS 2 - 恰好一次(严格保证)
mosquitto_pub -t "billing/payment" -m "Payment: $100" -q 2

# 订阅时指定最大QoS
mosquitto_sub -t "sensor/#" -q 1

QoS协议交互流程

QoS 0 流程

发布者发送
转发
投递
完成
PUBLISH
Broker
Subscriber
火力全发,不管结果

可能丢失消息

QoS 1 流程

发布者发送
Broker确认
完成
超时重传
重试成功
PUBLISH
PUBACK
需要确认

可能重复送达

QoS 2 流程

发布者发送
Broker收到
发布者释放
Broker完成
成功
超时重传
超时重传
PUBLISH
PUBREC
PUBREL
PUBCOMP
四次握手

保证恰好一次

开销最大

QoS选择建议表

应用场景 推荐QoS 理由
温度/湿度传感器 QoS 0 数据更新快,丢失一两次影响不大
烟雾/火灾告警 QoS 1 必须送达,可接受重复
远程控制指令 QoS 1 确保执行,重复执行通常安全
计费/交易数据 QoS 2 不能遗漏也不能重复
心跳/在线状态 QoS 0 频繁发送,性能优先
固件更新通知 QoS 1 需要送达,可重试
GPS位置追踪 QoS 0 实时性优先,数据量大

3.4 保留消息(Retained Messages)

保留消息机制

订阅者2(后订阅) 订阅者1(先订阅) Broker 发布者 订阅者2(后订阅) 订阅者1(先订阅) Broker 发布者 发布保留消息 保存消息 先订阅的客户端 后订阅的客户端 每个新订阅者 都会收到保留消息 PUBLISH topic Retained=TRUE Payload="状态:在线" SUBSCRIBE topic PUBLISH topic Payload="状态:在线" SUBSCRIBE topic PUBLISH topic Payload="状态:在线"

保留消息应用场景

保留消息用途
设备状态
最后已知位置
在线/离线状态
配置版本
传感器数据
最新读数
当前温度
当前湿度
配置信息
默认设置
系统参数
功能开关
通知公告
系统公告
维护通知
更新提示

保留消息使用示例

bash 复制代码
# 发布保留消息 - 设备状态
mosquitto_pub -t "device/gateway001/status" -m "online" -r

# 发布保留消息 - 最新温度
mosquitto_pub -t "sensor/livingroom/temperature" -m "25.5" -r

# 新订阅者会立即收到保留消息
mosquitto_sub -t "sensor/livingroom/temperature" -C 1

# 清除保留消息(发送空payload)
mosquitto_pub -t "device/gateway001/status" -r -n

# 查看$SYS中的保留消息
mosquitto_sub -v -t "$SYS/broker/retained messages/count"

保留消息注意事项

保留消息特性
✅ 每个主题只保留最后一条
✅ 新订阅者立即收到
⚠️ 会占用Broker内存
⚠️ 清除需发送空消息
应用: 设备最新状态
应用: 快速获取配置
注意: 避免滥用
方法: 使用-r -n清除

3.5 遗嘱消息(Last Will)

遗嘱消息工作原理

客户端连接

设置遗嘱
正常断开

DISCONNECT
异常断开

超时/网络故障
遗嘱不发送
Broker发送遗嘱消息
Connected
Disconnected
WillTriggered
PublishWill
异常断开时

自动发送预设消息

遗嘱消息流程

订阅者 Broker 客户端 订阅者 Broker 客户端 连接时设置遗嘱 正常运行 异常断开! 检测到客户端断开 收到离线通知 CONNECT Will Topic: device/status Will Message: "offline" Will QoS: 1 PUBLISH sensor/data "25°C" 转发数据 PUBLISH device/status "offline" (遗嘱消息)

遗嘱消息使用示例

bash 复制代码
# 连接时设置遗嘱消息
mosquitto_sub \
  -t "sensor/data" \
  -id "sensor001" \
  -will-topic "device/sensor001/status" \
  -will-payload "offline" \
  -will-qos 1 \
  -will-retain

# 在另一个终端监控设备状态
mosquitto_sub -v -t "device/#"

# 当客户端异常断开时
# 自动收到: device/sensor001/status offline

遗嘱消息应用场景

遗嘱消息场景
设备离线通知
网关掉线
传感器故障
移动设备离线
状态变更
在线→离线
活跃→休眠
正常→异常
告警触发
看门狗超时
心跳丢失
连接中断
清理状态
清除临时数据
释放资源
更新UI状态

遗嘱消息配置参数

参数 说明 示例
Will Topic 遗嘱消息主题 device/status
Will Message 遗嘱消息内容 "offline"
Will QoS 遗嘱QoS等级 1
Will Retain 是否保留遗嘱 true

3.6 Clean Session与持久会话

会话状态对比

Clean Session = false (持久会话)
客户端连接
创建持久会话
客户端断开
保留会话状态
缓存消息
重连时恢复
Clean Session = true (临时会话)
客户端连接
创建临时会话
客户端断开
立即清理会话
丢弃未发送消息

会话状态内容

会话状态
客户端信息
ClientID
用户名
订阅列表
消息队列
QoS 1未确认
QoS 2已收到
待发送消息
会话参数
Clean Session标志
Will遗嘱配置
保活时间

Clean Session使用场景

频繁在线
间歇在线
移动设备
选择会话类型
Clean Session=true
Clean Session=false
视情况而定
应用:

实时传感器

手机APP

临时监控
应用:

远程设备

水电表

农业传感器
考虑:

网络稳定性

消息重要性

电池寿命
✅ 减少服务器负担
✅ 离线消息不丢失
⚖️ 权衡性能与可靠性

会话恢复流程

Broker 客户端 Broker 客户端 首次连接 订阅主题 离线... 有QoS 1/2消息到达 缓存到会话队列 重连 发送缓存的离线消息 CONNECT CleanSession=false ClientID=device001 CONNACK 会话创建 SUBSCRIBE sensor/ SUBACK CONNECT CleanSession=false ClientID=device001 CONNACK 恢复会话 PUBLISH sensor/data (QoS 1) PUBACK

会话配置示例

bash 复制代码
# Clean Session = true (默认)
mosquitto_sub -t "sensor/#" -c

# Clean Session = false (持久会话)
mosquitto_sub -t "sensor/#" -id "persistent_client" -q 1

# 重连恢复会话
mosquitto_sub -t "sensor/#" -id "persistent_client"

3.7 Keep Alive(心跳机制)

心跳机制原理

Subscribers Broker 客户端 Subscribers Broker 客户端 建立连接 Keep Alive = 60秒 loop [每60秒] 网络故障... 1.5 x 60 = 90秒 未收到PINGREQ PINGREQ PINGRESP 判断客户端离线 发送遗嘱消息

Keep Alive时间设置

稳定有线网络
移动网络
不稳定网络
特别稳定
Keep Alive设置
网络环境?
60秒
30秒
15-20秒
120秒
✅ 减少流量
⚖️ 平衡流量与响应
📡 快速检测断线
🚀 最小开销
建议: 根据实际

环境测试调整

Keep Alive计算

bash 复制代码
# Keep Alive设置原则
# 最小值: 5秒(协议限制)
# 最大值: 约18小时(协议限制)
# 推荐值: 15-120秒

# 示例
mosquitto_sub -t "test/#" -k 30   # 30秒心跳
mosquitto_pub -t "test" -m "hello" -k 60   # 60秒心跳

3.8 Client ID规范

Client ID作用

Client ID
唯一标识客户端
关联持久会话
断线重连识别
ACL权限控制
必需: 1-23字符
持久会话必须固定
重连使用相同ID
权限配置依据

Client ID命名规范

Client ID命名
唯一性
全局唯一
不能重复
避免冲突
可读性
语义清晰
包含设备信息
便于调试
格式建议
前缀-设备ID-序号
小写字母+数字
连字符分隔
示例格式
dev-sensor001
app-user123-phone
gw-floor1-room2

Client ID生成策略

固定设备
移动应用
临时客户端
生成Client ID
设备类型?
设备唯一标识

MAC/序列号
用户ID+设备ID
随机生成
示例:

sensor-aabbccdd

gw-001-001
示例:

app-user123-ios

mobile-user456
示例:

temp-uuid123

client-random
✅ 稳定可追溯
✅ 用户关联
⚠️ 仅临时会话
持久会话推荐
临时会话可用

3.9 本章小结

核心概念总结

MQTT核心概念
发布订阅
主题设计
QoS等级
保留消息
遗嘱消息
会话管理
心跳机制
Client ID
解耦通信
层级清晰
3种QoS
最新状态
异常通知
离线消息
保持连接
唯一标识

最佳实践清单

概念 最佳实践 注意事项
主题设计 层级化、语义化 避免过深、使用通配符
QoS选择 根据数据重要性 平衡性能与可靠性
保留消息 设备状态、配置 及时清理、避免滥用
遗嘱消息 离线通知、状态变更 谨慎设置retain标志
会话类型 在线设备用clean 离线设备用持久
心跳时间 根据网络调整 太频繁浪费资源
Client ID 全局唯一、有意义 持久会话必须固定

🎯 思考与练习

理论题

  1. QoS 1 和 QoS 2 的主要区别是什么?什么场景应该使用 QoS 2?
  2. 保留消息和遗嘱消息有什么区别?各自适合什么场景?
  3. Clean Session 设置为 true 和 false 对消息接收有什么影响?

实践题

  1. 设计一个智能家居的主题结构,包含温度、湿度、灯光等设备
  2. 测试不同 QoS 等级在网络中断时的表现
  3. 配置遗嘱消息,观察客户端异常断开时的行为

进阶题

  1. 实现一个设备状态监控系统,使用保留消息和遗嘱消息
  2. 编写脚本测试持久会话的离线消息恢复
  3. 分析共享订阅在负载均衡中的应用
相关推荐
cskywit9 小时前
轻量级超分的双频域协同:深入源码解析 DMNet 架构设计
人工智能
liliwoliliwo9 小时前
D-FINE
人工智能·深度学习
摸鱼仙人~9 小时前
从Demo到可用:TodoWrite 幻觉问题优化指南
大数据·人工智能
独隅9 小时前
在 Windows 上部署 TensorFlow 模型的全面指南
人工智能·windows·tensorflow
人工智能培训9 小时前
系统集成与计算效率问题探析
人工智能·深度学习·机器学习·transformer·知识图谱
芯智工坊9 小时前
第5章 Mosquitto配置文件完全指南
网络·人工智能·mqtt·开源
Agent产品评测局9 小时前
汽车行业智能自动化平台选型,生产与供应链全优化:2026企业级智能体(Agent)实测与架构解析
java·人工智能·ai·chatgpt·架构·自动化
唐可盐9 小时前
【数据治理实践】第 15 期:数据质量提升实战——从“问题发现”走向“根因根治”
大数据·人工智能·数据治理·数字化转型·数据资产·数据资产入表
kishu_iOS&AI9 小时前
机器学习——归一化/标准化(特征工程预处理)
人工智能·算法·机器学习