什么是 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. Linux基础命令---cut

    cut 将文件中每一行的指定内容显示到标准输出. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法         cut [ ...

  2. git常用命令3

    一. Git 常用命令速查 git branch 查看本地所有分支git status 查看当前状态git commit 提交git branch -a 查看所有的分支git branch -r 查看 ...

  3. STM32f103C8T6 Bootloader设计(转)

    源:STM32f103C8T6 Bootloader设计 STM32F103c8t6通过串口实现IAP在线升级固件

  4. kafka生产者和消费者

    在使用kafka时,有时候为验证应用程序,需要手动读取消息或者手动生成消息.这个时候可以借助kafka-console-consumer.sh和kafka-console-producer.sh 这两 ...

  5. python中的property

    提示:这篇博文参考了两个博客,第一篇博文地址为:https://www.cnblogs.com/Lambda721/p/6132206.html,另一篇博文地址如下:关于python的property ...

  6. Python入门之面向对象的多态和继承

    本章内容 Python面向对象的多态和继承对比 ========================================= 在OOP程序设计中,当我们定义一个class的时候,可以从某个现有的 ...

  7. P1771 方程的解_NOI导刊2010提高(01)

    P1771 方程的解_NOI导刊2010提高(01) 按题意用快速幂把$g(x)$求出来 发现这不就是个组合数入门题吗! $k$个人分$g(x)$个苹果,每人最少分$1$个,有几种方法? 根据插板法, ...

  8. 06: Django Admin

    目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...

  9. bzoj 3505 数三角形 - 组合数学

    给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个.下图为4x4的网格上的一个三角形. 注意三角形的三点不能共线. Input 输入一行,包含两个空格分隔的正整数m和n. Output 输出 ...

  10. Socket:读写处理及连接断开的检测

    作为进程间通信及网络通信的一种重要技术,在实际的开发中,socket编程是经常被用到的.关于socket编程的一般步骤,这里不再赘述,相关资料和文章很多,google/baidu即可. 本文主要是探讨 ...