MQTT中QoS2的含义及四次握手丢包场景的精准投递疑问
MQTT QoS2 精准投递(Exactly Once)的核心逻辑解析
你忽略的核心是Message ID(消息ID)的唯一性校验和收发双方的状态持久化存储,这两个机制才是QoS2实现「Exactly Once」的关键:
核心机制拆解
- 唯一Message ID绑定:每个QoS2级别发布的消息都会携带一个唯一的16位Message ID,收发双方的所有状态流转都基于这个ID。
- 收发双端的状态存储:
- 接收方收到消息时,首先会检查本地是否已经记录过该Message ID的处理状态:
- 若未记录:处理消息,标记该ID为「已接收待确认」,然后发送PUBREC;
- 若已记录(比如这次是发送方超时重发的消息):直接跳过消息处理流程,重新发送PUBREC即可,不会重复执行业务逻辑。
- 发送方发送消息后,会进入「等待PUBREC」状态,若超时未收到回复,就重发相同Message ID的消息,而非生成新ID。
- 接收方收到消息时,首先会检查本地是否已经记录过该Message ID的处理状态:
针对你提到的场景的具体流转
当接收方收到消息但PUBREC丢失时:
- 发送方超时未收到PUBREC,重发同Message ID的消息;
- 接收方识别到该ID已处理过,直接回复PUBREC,不重复处理消息;
- 后续发送方收到PUBREC后发送PUBREL,接收方回复PUBCOMP,双方清除该ID的状态,流程闭环。
整个过程中,消息只会被接收方处理一次,完全符合「Exactly Once」的要求。
内容的提问来源于stack exchange,提问作者MichaelW
相关产品推荐
相关产品推荐

