QOS:quality of service,即 “质量服务”。
质量:通讯质量,即 “消息的可靠性”。
服务:保证消息可靠的机制。
MQTT服务端使用的EMQ,服务器系统Centos7.5。
1、 首先必须要了解MQTT是做什么用的。
2、 其次最起码要搭建过一个MQTT的服务端起来,下载一个客户端,发布/订阅玩一下。
小编推荐体验MQTT的环境:MQTT服务端推荐EMQ,MQTT客户端推荐paho。
好吧,没链接推荐个毛,对吧…
EMQ: http://www.emqtt.com/
paho: https://www.eclipse.org/paho/components/tool/
QOS0::至少0次,大白话就是只管发,不管收。
QOS1::至少1次。
QOS2: 刚好1次(这个是很多书、资料上的说法,其实这里更准确的说法应当是 “保证相同的消息只接收一条”)。
以上的次数指的均是 “接收方” 接收到数据的次数,即,Broker/Server、Subscriber。(除了Publisher不需要接收,服务端和订阅端均需要接收的嘛)
多提一嘴(可跳过),显然,从上面的QOS等级可以看出来:
1、QOS0不可靠,因此适合大量数据的传输,因为很大量的数据,完全避免不丢包是很难的,网络环境、现实环境什么的。想要保证的话,大量的数据,一般是要做断点续传。而且小编的经验,像类似 “轮询” 这样不断地得到一些检测数据,这种数据,中间丢几包是基本不会影响业务的。
2、QOS1可靠,一般的场景够用,因为总能接到数据嘛。缺点就是 “可能造成” 1条数据,接了多次。
3、QOS2严格可靠,保证相同的消息只接收一条,(请稍微构思一下内部的实现…虽然不复杂,但要一定的流程来保证的,对吧),在每一次通讯都这样执行的话,势必会造成性能的考验,因此小编对QOS2的意见是 “如非必要,慎用,特别是个人/小团队,没有那么多资金租用特别好的服务器”。
QOS等级是可以设置在 发布端(Publisher) 和 订阅端(Subscriber) 的。
因此,不同的设置组合,会有不同的效果。
小编来列一下这个组合(发布端:P、订阅端:S)
P(QOS0)、S(QOS0)
P(QOS0)、S(QOS1)
P(QOS0)、S(QOS2)
P(QOS1)、S(QOS0)
P(QOS1)、S(QOS1)
P(QOS1)、S(QOS2)
P(QOS2)、S(QOS0)
P(QOS2)、S(QOS1)
P(QOS2)、S(QOS2)
虽然理论上有以上这些组合,但是EMQ的服务端认为订阅端的QOS等级要基于发布端的QOS等级,
大白话就是 if( S(QOS) > P(QOS) ) { S(QOS) = P(QOS) ;},即:
P(QOS0)、S(QOS2) == P(QOS0)、S(QOS1) == P(QOS0)、S(QOS0)
P(QOS1)、S(QOS2) == P(QOS1)、S(QOS1)
实际上的组合是这样子的:
P(QOS0)、S(QOS0)
P(QOS1)、S(QOS0)
P(QOS1)、S(QOS1)
P(QOS2)、S(QOS0)
P(QOS2)、S(QOS1)
P(QOS2)、S(QOS2)
ip地址说明:
发布端(Publisher):192.168.126.1
EMQ服务端(Broker/Server):192.168.126.130
订阅端(Subscriber):192.168.126.128
P(QOS0)、S(QOS0):
P(QOS0)、S(QOS1):
P(QOS0)、S(QOS2):
以上三张图,证明P(QOS0)、S(QOS2) == P(QOS0)、S(QOS1) == P(QOS0)、S(QOS0)
P(QOS1)、S(QOS0) :
P(QOS1)、S(QOS1) :
P(QOS1)、S(QOS2) :
以上三张图,证明P(QOS1)、S(QOS2) == P(QOS1)、P(QOS1)
P(QOS2)、S(QOS0):
P(QOS2)、S(QOS1):
P(QOS2)、S(QOS2):
从以上的wireshark抓包截图,可以看出
QOS0: sender只向receiver发一次包,无论receiver能不能够收到。因此结论为receiver “至少0次或至多1次收到(相同内容/同一份)数据包” 。
QOS1:sender向receiver发包,如果receiver收到数据包,则回复sender,如果sender没有收到receiver的回复(就算已经成功发送了),则认为发生了丢包,会重发。因此结论为receiver “至少1次收到(相同内容/同一份)数据包” 。
QOS2:sender向receiver发一份(带有标识符)的数据包,如果receiver收到了数据包,则回复sender,如果sender没有收到receiver的回复(就算已经成功发送了),与QOS2不同的是,sender再次重发的数据包,会在receiver处先检查标识符,如果该数据包已缓存了,则丢弃sender重发的包,并重新回复sender,直到sender收到receiver的回复,sender再次发Publish Receive包到receiver,receiver收到之后回复Publish Complete包给sender,如此一套流程标志着此次通讯的完成。因此结论为receiver “刚好或只收到1次相同内容/同一份)数据包” 。
QOS1和QOS2的差异在于QOS2的数据包带有标识符,并且receiver需要收到sender再发的Publish Receive包,以确定消息收到的事实已被sender得知,最后以向sender回复Publish Complete来标志着此次通讯的完整、可靠。