如果设备运行在网络延迟高或者出现网络断线的环境下,只依靠 TCP 协议是不能完全保证消息可以发送到服务端的。
客户端发送数据到服务端的时候,如果网络延迟高 TCP 是可以保证数据发送到服务端的,但是在发送数据的过程中 TCP 因为网络原因断开了,当客户端重新连接后,TCP 不会重新发送这条数据。
因此,MQTT 协议提供了 3 种消息服务质量等级(Quality of Service),保证了在不同的网络环境下消息传递的可靠性:
QoS 0
发送方发送一条消息后,不会关心接收方有没有回复 ACK,就是说发送方不会关心消息有没有发送到接收方。
因为发送方不关心 ACK 就没有重传机制,所以当 TCP 断开连接后,消息就会丢失。
QoS 1
发送方添加了重传机制,没有收到接收方返回的 ACK 报文,就会一直重新发送。
有可能出现,接收方返回了 ACK 报文,但是发送方没有收到,这就导致发送方会重新发送,而接收方就会收到两个相同的报文。
QoS 2
QoS 2 解决了 QoS 0、1 消息可能丢失或者重复的问题,保证消息只发送一次。
QoS 2 流程:
-
发送方发送数据到接收方,接收方会返回 REC 报文(代替 ACK),发送方没有收到 REC 报文会继续重发。
-
收到 REC 后,发送方再发送 REL 报文,通知接收方把刚才发送的那个数据标记为可用,然后接收方返回 COMP 报文,发送方没有收到会继续重发 REL。
-
收到 COMP 报文后,流程正式完成了。
不同 QoS 的性能有差距么?
以 EMQX 为例,在相同的硬件配置下进行点对点通信,通常 QoS 0 与 QoS 1 能够达到的吞吐比较接近,不过 QoS 1 的 CPU 占用会略高于 QoS 0,负载较高时,QoS 1 的消息延迟也会进一步增加。而 QoS 2 能够达到的吞吐一般仅为 QoS 0、1 的一半左右。
参考资料
https://www.emqx.com/zh/blog/what-is-the-mqtt-protocol
https://www.emqx.com/zh/blog/introduction-to-mqtt-qos
https://www.emqx.com/zh/mqtt-guide
标签:QoS,ACK,什么,TCP,发送,接收,报文 From: https://www.cnblogs.com/cdsy/p/17651984.html