QoS 0(最多一次)
QoS 0(最多一次)
Section titled “QoS 0(最多一次)”本节介绍 MQTT QoS 0(最多一次送达)的工作原理、使用场景和技术实现。学习完成后,您将能够:
- 理解 QoS 0 的消息传递机制
- 确定哪些场景适合使用 QoS 0
- 在 Node-RED 和 ESP32 中配置 QoS 0
- 解释不同 QoS 级别的选择理由
在开始本节之前,请确保:
- 理解 MQTT 协议基础
- Mosquitto Broker 已运行
- 已安装 MQTT 命令行工具
QoS 0 Overview
Section titled “QoS 0 Overview”What is QoS 0?
Section titled “What is QoS 0?”QoS 0(At most once,最多一次)是 MQTT 中最基础的 QoS 级别,提供”尽力而为”的消息投递。
核心特点:
- 发送者只发送一次消息
- 不需要任何确认(ACK)
- 不重试失败的消息
- 不存储消息状态
Message Flow
Section titled “Message Flow”Publisher Broker Subscriber │ │ │ │─── PUBLISH ──────────→│ │ │ (QoS=0, no ID) │ │ │ │─── PUBLISH ──────────→│ │ │ (QoS=0, no ID) │ │ │ │ │ ✗ No acknowledgement │ │ │ ✗ No retry │ ✗ No acknowledgement│ │ ✗ No state stored │ ✗ No retry │ │ │ │协议层面:
- 发布者发送 PUBLISH 报文(QoS=0,不包含 Packet ID)
- 发布者发送后立即丢弃该消息的状态
- Broker 接收后转发给订阅者
- 订阅者接收消息但不发送确认
- 任何环节失败→消息丢失
Characteristics
Section titled “Characteristics”Reliability vs Performance
Section titled “Reliability vs Performance”| 指标 | QoS 0 | 对比其他级别 |
|---|---|---|
| 消息头开销 | 最小(2 字节) | QoS 1: 4 字节 |
| 网络往返 | 0 次 | QoS 1: 1 次 |
| 消息丢失率 | 可能(但低) | Q0S 1: 极低 |
| 消息重复率 | 无 | QoS 1: 可能 |
| 发布者资源 | 最低 | QoS 1: 需要存储 |
| Broker 资源 | 最低 | QoS 1: 需要存储 |
Failure Scenarios
Section titled “Failure Scenarios”可能的消息丢失场景:
1. 发布者到 Broker 网络中断 Publisher ──✗──→ Broker 消息在传输中丢失,发布者不知情
2. Broker 转发失败 Broker ──✗──→ Subscriber 订阅者未收到消息,Broker 不重试
3. 订阅者离线 订阅者在消息到达时不在线 消息不被存储(非持久会话)
4. Broker 崩溃 内存消息丢失(无持久化)When to Use QoS 0
Section titled “When to Use QoS 0”Recommended Scenarios
Section titled “Recommended Scenarios”| 场景 | 推荐 QoS | 理由 |
|---|---|---|
| 高频传感器数据(1 秒/次) | QoS 0 | 丢失一条无关紧要,下次有更新 |
| 无线遥测数据 | QoS 0 | 低带宽、高性能需求 |
| 位置更新(GPS) | QoS 0 | 旧数据没用,需要最新值 |
| 日志/调试消息 | QoS 0 | 丢失不影响系统运行 |
| 非关键状态通知 | QoS 0 | 偶尔丢失可接受 |
Not Recommended Scenarios
Section titled “Not Recommended Scenarios”| 场景 | 推荐 QoS | 理由 |
|---|---|---|
| 设备控制命令 | QoS 1/2 | 控制命令不能丢失 |
| 支付交易消息 | QoS 2 | 必须精确一次 |
| 告警通知 | QoS 1 | 告警不可丢失 |
| 配置更新 | QoS 1 | 配置需要可靠到达 |
| 设备固件更新 | QoS 1 | 关键操作 |
Implementation
Section titled “Implementation”ESP32 with PubSubClient
Section titled “ESP32 with PubSubClient”#include <PubSubClient.h>
// 使用 QoS 0 发布传感器数据void publishSensorData(float temperature, float humidity) { char payload[64]; snprintf(payload, 64, "{\"temp\":%.1f,\"hum\":%.1f}", temperature, humidity);
// publish 的第三个参数是 QoS,第四个是 retain // publish(topic, payload, length, retained) boolean result = mqttClient.publish( "sensors/environment", payload, false // QoS 0 );
if (result) { Serial.println("Published with QoS 0"); } else { // QoS 0 下失败通常表示连接已断开 Serial.println("Publish failed - connection issue"); }}
// 配置 QoS 0 订阅void setupMQTT() { mqttClient.setServer(MQTT_BROKER, 1883); mqttClient.setCallback(callback); mqttClient.connect("esp32_client");
// subscribe 的第二个参数是 QoS // subscribe(topic, qos) mqttClient.subscribe("sensors/control", 0); // QoS 0}Node-RED MQTT Node Configuration
Section titled “Node-RED MQTT Node Configuration”Node-RED MQTT In 节点配置:├── Server: [MQTT Broker]├── Topic: sensors/environment├── QoS: 0 (At most once) ← 选择├── Output: a parsed JSON object└── Name: Environment Data
MQTT Out 节点配置:├── Server: [MQTT Broker]├── Topic: sensors/control├── QoS: 0 (At most once) ← 选择├── Retain: false└── Name: Control CommandMosquitto Command Line
Section titled “Mosquitto Command Line”# 发布 QoS 0 消息(默认)mosquitto_pub -h localhost -t "test/qos0" -m "hello" -q 0
# 订阅 QoS 0mosquitto_sub -h localhost -t "test/qos0" -q 0
# 验证 - 查看 Broker 日志的输出docker logs mosquitto --tail 10Performance Benchmarks
Section titled “Performance Benchmarks”QoS 0 Performance Data
Section titled “QoS 0 Performance Data”| 场景 | QoS 0 | QoS 1 | QoS 2 |
|---|---|---|---|
| 消息延迟 (局域网) | < 1ms | 1-2ms | 3-5ms |
| 消息吞吐量 (1k payload) | ~50,000/s | ~20,000/s | ~8,000/s |
| 带宽开销 (per msg) | 2 字节 | ~6 字节 | ~12 字节 |
| CPU 占用 | 低 | 中 | 高 |
| 内存占用 | 无状态 | 存储消息直到确认 | 完整的握手状态 |
QoS 0 Usage Tips
Section titled “QoS 0 Usage Tips”- ✅ 推荐: 在高频传感器数据场景默认使用 QoS 0
- ✅ 推荐: 配合保留消息使用,保证新订阅者获得最新值
- ✅ 推荐: 在稳定的有线网络环境中放心使用
- ❌ 避免: 关键控制命令使用 QoS 0
- ❌ 避免: 在不可靠的移动网络中使用 QoS 0
- ❌ 避免: 期望 QoS 0 保证消息投递的可靠性
验证 QoS 0 行为
Section titled “验证 QoS 0 行为”# 测试步骤# 终端 1: 以 QoS 0 订阅mosquitto_sub -h localhost -t "qos0/test" -q 0 -v
# 终端 2: 以 QoS 0 发布mosquitto_pub -h localhost -t "qos0/test" -q 0 -m "QoS 0 message"
# 验证: 订阅者接收消息# 验证: 消息丢失时不重试Pre-sales Communication
Section titled “Pre-sales Communication”如何解释 QoS 0
Section titled “如何解释 QoS 0”Q: 传感器数据丢失了怎么办?
A: 我们的温度传感器每 3 秒发送一次数据。如果某次数据丢失,3 秒后就会收到新的数据。对于环境监测来说,丢失一个数据点不会影响整体趋势的判断。如果需要更高的可靠性,可以为关键传感器设置 QoS 1。
Q: 为什么不在所有场景都用最高可靠性?
A: 更高的可靠性意味着更多的网络流量和处理延迟。对于几秒钟就更新一次的传感器数据,使用 QoS 0 可以减少 90% 的网络开销,同时不会对监控效果产生明显影响。
Summary
Section titled “Summary”本节要点总结:
- QoS 0 定义:最多一次送达,发送后不确认、不重试
- 可靠性:最低,消息可能丢失
- 性能:最佳,零额外网络开销
- 适用场景:高频传感器数据、非关键遥测、调试日志
- 不适用场景:控制命令、告警通知、支付交易