什么是 QoS ?

QoS (Quality of Service) 是发送者和接收者之间,对于消息传递的可靠程度的协商。

QoS 的设计是 MQTT 协议里的重点。作为专为物联网场景设计的协议,MQTT 的运行场景不仅仅是 PC,而是更广泛的窄带宽网络和低功耗设备,如果能在协议层解决传输质量的问题,将为物联网应用的开发提供极大便利。

三个 QoS 级别简介

在 MQTT 协议里,定义了三个级别的 QoS,由低到高分别是:

  • 最多一次 (QoS0)
  • 至少一次 (QoS1)
  • 有且仅有一次 (QoS2)

QoS0 是最低级别,基本上等同于 Fire and Forget 模式,发送者发送完数据之后,不关心消息是否已经投递到了接收者那边。

QoS1 是中间级别,保证消息至少送达一次。MQTT 通过简单的 ACK 机制来保证 QoS1。

QoS2 是最高级别,保证到且仅到一次。这通过更加复杂的消息流程保证。

QoS 级别越高,流程越复杂,系统资源消耗越大。应用程序可以根据自己的网络场景和业务需求,选择合适的 QoS 级别:

比如在同一个子网内部的服务间的消息交互往往选用 QoS0;而通过互联网的实时消息通信往往选用 QoS1;QoS2 使用的场景相对少一些,能想到的如国防武器,医疗设备等应用场景。

既然 QoS 是发送者和接收者之间的质量协定,在 MQTT 协议的 Client - Broker - Client 架构里,QoS 就需要分成两部分来讨论:

  1. 从发送者到 Broker 之间消息传递的 QoS。这需要由发送者在 MQTT PUBLISH 消息里设置 QoS 级别。
  2. 从 Broker 到接收者之间消息传递的 QoS。这需要接收者在订阅 Topic 时,设置 SUBSCRIBE 消息里的 QoS 级别。
什么是Quality of Service
Quality of Service等级是发送与接收端的一种关于保证交付信息的协议。一共有3 个QoS 等级:
  1. 最多一次(0)
  2. 最少一次(1)
  3. 只一次(2)
QoS 总是会有2个不同的交付信息组成:客户端(client)推送给代理(broker),代理(broker)推送给订阅的客户端(client)。因为他们有些微妙的不同,所以我们需要分开的来讲述他们。对于客户端推送给代理的QoS 等级,取决于客户端为某特定信息设定的QoS等级。更直观一点的说就是,当客户端推送信息给代理的时候,QoS的等级是由客户端决定的。当代理传送一条信息给订阅的客户端的时候,会使用这个客户端之前设定的QoS等级。
 
为什么QoS如此重要
 
QoS 是MQTT的一个主要的功能。它使得在一个不稳定的网络环境里的信息交换更加的简单,因为协议控制了中继并保证了信息的交付,忽略了不可靠的下层的交互。并且,它授权给客户端来根据客户端的程序逻辑,网络可靠程度来决定QoS等级。
 
QoS是如何工作的?
那么QoS是如何在MQTT协议中实现的呢?让我们来一个等级一个等级的看一下。
 
QoS 0 —— 最多1次
最小的等级就是 0。并且它保证一次信息尽力交付。一个消息不会被接收端应答,也不会被发送者存储并再发送。这个也被叫做“即发即弃”。并且在TCP协议下也是会有相同的担保。
QoS 1 ——最少1次
当使用QoS 等级1 时, 它保证信息将会被至少发送一次给接受者。但是消息也可能被发送两次甚至更多。

发送者将会存储发送的信息直到发送者收到一次来自接收者的PUBACK格式的应答。
PUBLISH 与PUBACK的关联是通过比较数据包中的packet identifier完成的。如果在特定的时间内(timeout)发送端没有收到PUBACK应答,那么发送者会重新发送PUBLISH消息。如果接受者接收到QoS为1 的消息,它会立即处理这里消息,比如把这个包发送给订阅该主题的接收端,并回复PUBACK包。
 
The duplicate(DUP)flag,用来标记PUBLISH 被重新分发的情况。仅仅是为了内部使用的目的,并且当QoS 为1 是不会被broker 或者client处理。接受者都会发送PUBACK消息,而不管DUP flag。

QoS 2

最高的QoS就是2,它会确保每个消息都只被接收到的一次,他是最安全也是最慢的服务等级。
如果接收端接收到了一个QoS 的PUBLISH消息,它将相应地处理PUBLISH消息,并通过PUBREC消息向发送方确认。

直到他发出一个PUBCOMP包为止,接收端都保存这个包packet identifier。这一点很重要,因为它避免了二次处理同一个PUBLISH包。 当发送者接收到PUBREC的时候,它可以放弃最开始的publish了,因为它已经知道另一端已经接收到消息,他将保存PUBREC并且回复PUBREL。
当接收端接收到PUBREL,它就可以丢弃所有该包的存储状态并回复PUBCOMP。当发送端接收到PUBCOMP时也会做同样的处理。
 
当整个流程结束的时候,所有的参与者都确定消息被正确的发送和送达了。
 
无论什么时候,一个包丢失了,发送端有责任在特定时间后重新发送最后一次发送的消息。接收端有责任响应每一个指令消息。
 
须知:
 
QoS 向下兼容
QoS流,在发送端和接收端是两件不同的事情,当然发送端与接收端QoS的等级也可以不一样。在发送端与broker之间,发送端定义了QoS等级。当broker发送消息到接收端是,接收端决定了QoS的等级。 

Packet identifiers 是每个消息流唯一的

在一个client和broker之间,每个packet identiier都是唯一的。如果一个消息流结束了,相同的packet identifier可以在任意时间被重用。这也就是packet identifier没有必要比65535还要大的原因,因为一个client发送如此大的消息去没有结束这个消息流是不切实际的。

MQTT协议QoS服务质量 (Quality of Service 0, 1 & 2)概念学习的更多相关文章

  1. Quality of Service 0, 1 & 2

    来自:http://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels Quality of Servi ...

  2. mqtt协议系统设计参考

    作者:极寒链接:https://zhuanlan.zhihu.com/p/28525517来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 回顾自己的工作经历最遗憾的是没 ...

  3. kubernetes之资源限制及QOS服务质量

    1.什么是资源限制? 1.1在kubernetes集群中,为了使得系统能够稳定的运行,通常会对Pod的资源使用量进行限制.在kubernetes集群中,如果有一个程序出现异常,并且占用大量的系统资源, ...

  4. neutron qos Quality of Service

    Quality of Service advanced service is designed as a service plugin. The service is decoupled from t ...

  5. MQTT 协议学习: QoS等级 与 会话

    背景 QoS 等级 与 通信的流程有关,直接影响了整个通信.而且篇幅比较长,所以我觉得应该单独拎出来讲一下. 概念 QoS 代表了 服务质量等级. 设置上,由2 位 的二进制控制,且值不允许为 3(0 ...

  6. MQTT协议(一)

    MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约.轻量,易于使用,针对受限环境(带宽低.网络延迟高.网络通信不稳定),可以简单 ...

  7. (76)深入浅出Mqtt协议

    物联网(Internet of Things,IoT)时代机器之间(Machine-to-Machine,M2M)的大规模沟通需要发布/订阅(Publish/Subscribe)模式,轻量级.易扩展的 ...

  8. 基于RabbitMQ的MQTT协议及应用

    MQTT的开源代码地址先贴在这里:https://github.com/mqtt/mqtt.github.io/wiki/servers MQTT定义: MQTT(Message Queuing Te ...

  9. MQTT协议笔记之消息流

    前言 前面的笔记已把所有消息类型都过了一遍,这里从消息流的角度尝试解读一下. 网络故障 在任何网络环境下,都会出现一方连接失败,比如离开公司大门那一刻没有了WIFI信号.但持续连接的另一端-服务器可能 ...

随机推荐

  1. IO(字节流)

    1. 字节流类以InputStream 和 OutputStream为顶层类,他们都是抽象类(abstract) 2. 最重要的两种方法是read()和write(),它们分别对数据的字节进行读写.两 ...

  2. JDBC报错记录

    用JDBC连接oracle时 有如下问题: 问题一.java.lang.ClassNotFoundException: oracle.jdbc.driver.oracledriver 解决: 可以在环 ...

  3. WireShark学习

    1.打开wireshark->Capture->Interface->选择你的网卡(选中)->Start 2.OK抓包开始,工具栏上有stop,点击停止抓包 3.过滤,这个你可 ...

  4. 20145205武钰_Exp5 MSF基础应用

    20145205武钰_Exp5 MSF基础应用 实验后回答问题 exploit:这个词本身只是利用,但是它在黑客眼里就是漏洞利用.有漏洞不一定就有Exploit(利用).有Exploit就肯定有漏洞. ...

  5. C++ 单例模式(转载)

    转载:http://www.cnblogs.com/cxjchen/p/3148582.html 转载:http://blog.csdn.net/hackbuteer1/article/details ...

  6. Python3基础 函数 无参数无返回值 调用会输出hello world的函数

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  7. Go第十一篇之编译与工具

    Go 语言的工具链非常丰富,从获取源码.编译.文档.测试.性能分析,到源码格式化.源码提示.重构工具等应有尽有. 在 Go 语言中可以使用测试框架编写单元测试,使用统一的命令行即可测试及输出测试报告的 ...

  8. 硬盘分区表知识—详解硬盘MBR

    硬盘是现在计算机上最常用的存储器之一.我们都知道,计算机之所以神奇,是因为它具有高速分析处理数据的能力.而这些数据都以文件的形式存储在硬盘 里.不过,计算机可不像人那么聪明.在读取相应的文件时,你必须 ...

  9. Maximum GCD (stringstream)题解

    Given the N integers, you have to find the maximum GCD (greatest common divisor) of every possiblepa ...

  10. Is it bad to rely on foreign key cascading? 外键 级联操作

    Is it bad to rely on foreign key cascading? I'll preface前言 this by saying that I rarely delete rows ...