会话与消息管理
TMQTT 提供完善的会话管理和消息可靠性保障机制,确保消息在各种网络条件下都能正确传递。
会话类型
客户端连接时可以选择两种会话模式:
临时会话(Clean Session = true)
客户端断开后,所有会话状态(订阅关系、离线消息等)立即清除。下次连接时从头开始。
适用场景:实时数据展示、不需要消息回溯的轻量设备。
持久会话(Clean Session = false)
客户端断开后,会话状态保留,等待客户端重连后恢复。包括:
- 订阅关系自动恢复
- 断开期间的消息自动缓存,重连后按序投递
- 正在等待确认的消息(Inflight)保留并重新发送
适用场景:需要消息不丢失的业务系统、网络不稳定的移动设备。
消息可靠性
TMQTT 通过飞行窗口(Inflight Window)机制管理消息的可靠传递:
- QoS 1:TMQTT 发送消息后等待客户端回复 PUBACK。在收到确认前,消息保留在飞行窗口中,超时自动重传。
- QoS 2:完整的四次握手(PUBLISH → PUBREC → PUBREL → PUBCOMP),确保消息恰好传递一次。
- 飞行窗口大小:默认 32,可通过
session.max_inflight配置。窗口越大,并发确认的消息越多,但内存占用也越高。
离线消息
当持久会话的客户端处于断开状态时,发往该客户端订阅主题的消息会被缓存到离线队列。
工作流程:
- 客户端断开 → TMQTT 检测到离线状态
- 新消息到达 → 写入该客户端的离线消息队列
- 客户端重连(Clean Session = false) → TMQTT 恢复会话,将离线消息按序投递
队列上限:通过 storage.max_offline_messages 配置(默认 1000 条),设为 0 表示不限制。超过上限时最旧的消息会被丢弃。
保留消息持久化
如果启用了持久化存储后端,Retain 消息会被持久化保存。TMQTT 重启后自动加载所有保留消息,无需等待客户端重新发布。
内存存储模式下,保留消息仅存在于内存中,重启后丢失。
存储后端选择
| 后端 | 特点 | 适用场景 |
|---|---|---|
| 内存存储 | 速度快,重启数据丢失 | 开发测试、允许短暂中断的场景 |
| RocksDB 持久化 | 重启不丢失,需要磁盘空间 | 生产环境,要求数据持久化 |
选择方式通过 storage.storage_type 配置(memory 或 rocksdb)。
注意:RocksDB 存储需要在编译时启用
--features rocksdb。
会话过期与清理
持久会话不会永久保留。超过 session.session_expiry_sec(默认 86400 秒 = 1 天)未被客户端重连的会话会被自动清理,释放占用的资源。
TMQTT 后台每 30 秒执行一次清理任务,移除:
- 过期的持久会话
- 对应的离线消息队列
- 残留的订阅关系
优雅关闭
当 TMQTT 收到关闭信号(SIGTERM 或 Ctrl+C)时,会执行优雅关闭流程:
- 停止接受新连接
- 等待现有连接处理完成(最多等待 30 秒)
- 将仍处于连接状态的持久会话保存到存储后端
- 进程退出
这确保了 Broker 重启后,持久会话的客户端重连时能恢复完整状态。
Copyright (c) 2026 桃子 TaoZi.Pub https://taozi.pub | MIT License