MQTT之QOS机制分析

12 篇文章 0 订阅
2 篇文章 0 订阅

MQTT之QOS机制分析

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/

QOS等级

QOS0::至少0次,大白话就是只管发,不管收。
QOS1::至少1次。
QOS2: 刚好1次(这个是很多书、资料上的说法,其实这里更准确的说法应当是 “保证相同的消息只接收一条”)。

以上的次数指的均是 “接收方” 接收到数据的次数,即,Broker/Server、Subscriber。(除了Publisher不需要接收,服务端和订阅端均需要接收的嘛)

多提一嘴(可跳过),显然,从上面的QOS等级可以看出来:
1、QOS0不可靠,因此适合大量数据的传输,因为很大量的数据,完全避免不丢包是很难的,网络环境、现实环境什么的。想要保证的话,大量的数据,一般是要做断点续传。而且小编的经验,像类似 “轮询” 这样不断地得到一些检测数据,这种数据,中间丢几包是基本不会影响业务的。
2、QOS1可靠,一般的场景够用,因为总能接到数据嘛。缺点就是 “可能造成” 1条数据,接了多次。
3、QOS2严格可靠,保证相同的消息只接收一条,(请稍微构思一下内部的实现…虽然不复杂,但要一定的流程来保证的,对吧),在每一次通讯都这样执行的话,势必会造成性能的考验,因此小编对QOS2的意见是 “如非必要,慎用,特别是个人/小团队,没有那么多资金租用特别好的服务器”。

Publisher与Subscriber的QOS组合

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)

WireShark证实这一切

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(QOS0)的截图
P(QOS0)、S(QOS1):
P(QOS0)、S(QOS1)的截图
P(QOS0)、S(QOS2):
P(QOS0)、S(QOS2)的截图
以上三张图,证明P(QOS0)、S(QOS2) == P(QOS0)、S(QOS1) == P(QOS0)、S(QOS0)

P(QOS1)、S(QOS0) :
P(QOS1)、S(QOS0) 的截图
P(QOS1)、S(QOS1) :
P(QOS1)、S(QOS0) 的截图
P(QOS1)、S(QOS2) :
P(QOS1)、S(QOS2)的截图
以上三张图,证明P(QOS1)、S(QOS2) == P(QOS1)、P(QOS1)

P(QOS2)、S(QOS0):
P(QOS2)、S(QOS0)的截图
P(QOS2)、S(QOS1):
P(QOS2)、S(QOS1)的截图
P(QOS2)、S(QOS2):
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来标志着此次通讯的完整、可靠。

  • 14
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
MQTT(Message Queuing Telemetry Transport)是一种轻量级的通信协议,用于在物联网设备之间进行消息传输。在MQTT中,订阅(subscribe)是一种客户端向MQTT代理服务器注册兴趣以接收特定主题消息的操作。QoS(Quality of Service)是MQTT中用于定义消息传输质量的参数。 在MQTT中,有三个不同的QoS级别可供选择: 1. QoS 0(“至多一次”):消息以最多一次的方式传输。在这个级别下,消息可能会丢失或重复。 2. QoS 1(“至少一次”):消息至少传输一次,但可能会重复。 3. QoS 2(“只有一次”):消息确保只传输一次,不会出现重复。 当订阅一个主题时,可以指定所需的QoS级别。该级别将确定代理服务器传递该主题的消息时所采取的传输保证机制。 例如,使用MQTT客户端库(如Paho MQTT)可以使用以下代码进行订阅操作: ```python import paho.mqtt.client as mqtt def on_message(client, userdata, msg): # 处理接收到的消息 print(msg.topic + " " + str(msg.payload)) client = mqtt.Client() client.on_message = on_message client.connect("mqtt.example.com", 1883, 60) client.subscribe("my/topic", qos=1) # 指定QoS级别为1 client.loop_forever() ``` 在上述代码中,通过调用`subscribe`函数并指定`qos=1`,订阅了名为"my/topic"的主题,并将QoS级别设置为1。这意味着代理服务器将以至少一次的方式传输该主题的消息。 需要注意的是,发布(publish)消息的客户端也可以指定消息的QoS级别。发布和订阅的QoS级别可以独立设置,以满足不同的传输需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值