什么是 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. ACM题目———— 一种排序(STL之set)

    描述 输入 第一行有一个整数 0<n<10000,表示接下来有n组测试数据:每一组第一行有一个整数 0<m<1000,表示有m个长方形:接下来的m行,每一行有三个数 ,第一个数 ...

  2. 如何向GLSL中传入多个纹理

    http://blog.csdn.net/huawenguang/article/details/41245871 如何向GLSL中传入多个纹理 这几天在研究如何实现用GLSL对多个纹理进行融合处理, ...

  3. 20145104张家明 《Java程序设计》第9周学习总结

    20145104张家明 <Java程序设计>第9周学习总结 教材学习内容总结 第16章 -撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找. -JDBC目的:让Java ...

  4. 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 2 章 答案

    判断对错1.编写程序的好方法是立即键入一些代码,然后调试它,直到它工作.2.可以在不使用编程语言的情况下编写算法.3.程序在写入和调试后不再需要修改.4.Python 标识符必须以字母或下划线开头.5 ...

  5. 【SVN】Linux搭建SVN服务

    1.yum安装svn yum install -y subversion 日志打印 Loaded plugins: fastestmirror Determining fastest mirrors ...

  6. EasyUI ---- draggable可拖动的用法

    <link href="~/Scripts/easyui1.5/themes/default/easyui.css" rel="stylesheet" / ...

  7. python ros 关闭节点

    def myhook(): print "shutdown time!" rospy.on_shutdown(myhook) 或 rospy.signal_shutdown(rea ...

  8. python 集合的运算

    x = frozenset([, , , , ]) y = frozenset([, , , , ]) #如果x与y没有公共元素,返回true print(x.isdisjoint(y)) #返回x与 ...

  9. STL_iterator返回值

    1. iterator的类型 有 单向的/双向的/可以随意移动的... 2. 一些 容器/算法 的返回值 是 iterator类型的,如何确定 返回的 iterator是什么类型的? 3.

  10. 《剑指offer》第三_一题(找出数组中重复的数字,可改变数组)

    // 面试题3(一):找出数组中重复的数字 // 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, // 也不知道每个数字重复了几次.请 ...