MQTT Illustrated - The QoS Levels

本系列文章以当前普遍使用的 MQTT 版本 3.1.1 为例,结合 wireshark 工具,详细解析 MQTT 协议里的消息流程和细节。

什么是 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 级别。

实例分析

本实例中使用的工具:

QoS 0 发布订阅

这个例子里,我们的 MQTT Client 使用 QoS0 订阅主题 t/1, 然后发布 QoS0 消息 "hi" 到主题 t/1:

Subscribe 的消息体里包含了 QoS 信息,这是我们前面说的第二类QoS,即 "从 Broker 到接收者之间消息传递的 QoS":

  • qos0-sub

接下来是连续两个 PUBLISH 消息。

第一个是从 Client 到 Broker 的,因为 EMQ 和 MQTT Box 都是运行在本机上的,所以显示的 IP 都是 "127.0.0.1",但还是可以通过端口号区分开。62814 是 MQTT Box 的客户临时端口,而 1883 是 EMQ 的 Listening 端口:

  • qos0-pub

    注意跟 Subscribe 消息不同的是,Publish 消息的 QoS 信息作为标志位包含在MQTT 消息头里,而不是消息体中。

第二个是从 Broker 下发到 Client 的。这是因为我们前面刚刚订阅了 t/1 主题:

  • qos0-recv

QoS 1 发布订阅

这个例子里,我们的 MQTT Client 使用 QoS1 订阅主题 t/2, 然后发布 QoS1 消息 "hi" 到主题 t/2:

Subscribe 部分跟 QoS 0 类似,只不过消息体里的 QoS 信息变成了 1。

但 Publish 消息时,多了一个 PUBACK。

从 Client 到 Broker 的 PUBLISH 消息的消息头里,可以看到它的 QoS 设置为 1 :

  • qos1-pub

紧接着 Broker 回复 PUBACK,PUBLISH 消息和 PUBACK 消息通过相同的 Message Identifier 关联起来:

  • qos1-pub-ack

如果 Client 没有收到 PUBACK 的话,它将会重试,再次发送 Publish 消息。

下一个 Publish 消息是从 Broker 下发到 Client 的,紧跟着的 PUBACK 是从 Client 回复给 Broker 的。消息内容跟上面类似。

QoS 2 发布订阅

这个例子里,我们的 MQTT Client 使用 QoS2 订阅主题 t/3, 然后发布 QoS2 消息 "hi" 到主题 t/3:

Subscribe 部分跟 QoS 0 和 QoS 1 的类似,只不过消息体里的 QoS 信息变成了 2。

接下来的 Publish 消息流程变得复杂了一些:

  • qos2-sequence
  • qos2-pub-group.png

当 MQTT Broker 收到 QoS2 的 PUBLISH 消息的时候,会处理这条消息并回复 PUBREC (Publish Received)。

MQTT Broker 会将消息体中的消息 ID 暂存下来。暂存消息 ID 是为了保证唯一性,如果 Broker 再次收到一条重复的 PUBLISH 消息,就可以将其忽略掉。

Client 发送完最初的 PUBLISH 消息之后,还不能马上删除这条消息的缓存,以便必要时重发。当 Client 收到 Broker 发来的 PUBREC 回复之后,知道对方已经收到了自己发出的 PUBLISH,此时就可以放心地将缓存删除了。Client 保存一下 PUBREC 里的消息ID,并发送 PUBREL (Publish Release) 消息给 Broker,以通知 Broker 删除状态缓存。

Broker 收到 PUBREL 后,知道 Client 已经不会再发送多余的 Publish 过来了,此时可以放心的删除之前已经存储的消息 ID,并回复 PUBCOMP。

当 Client 收到 PUBCOMP 时,可以删除所有缓存,因为它知道现在不需要重发 PUBREL 消息了。

另外一侧,从 Broker 下发到设备的流程与此相同。

QoS 降级

因为 QoS 分为 发送到 Broker 的 QoS从 Broker 接收的 QoS 两部分,所以最终收到的 QoS 等级跟这两部分都有关系:

如果发送者发送了一个 QoS2 的消息,但是接收者订阅时使用的是QoS1,那么接收到的消息等级就是 QoS1。这个叫做 QoS 降级。

  • qos-downgrade

作者: liuxy@emqx.io

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容