QoS的报文收发流程


QoS 0

最多交付一次,消息有可能丢失,最低的QoS等级,没有任何的机制,不需要等待确认和重传,只要保证消息发送,也可能到达不了接收端

QoS0消息发送流程:

  1. 发送端调用API发送消息
  2. 消息将被拷贝内核层的至发送缓冲区中
  3. 发送缓冲区的消息会在合适的时机被发送到网络中
  4. 经过路由跳转以后,消息被接收端的网卡接收,然后消息来到接收端的接收缓冲区
  5. 接收缓冲区有了消息,接收端的内核层就会通知上层应用读取消息

只有上层应用读取到了消息,消息才算真正到达了接收端,在之前的任意步骤出现网络断开,这些传输消息就会丢失,这也是消息可能丢失的原因

QoS 1

至少交付一次,消息有可能重复,为了解决消息丢失的问题,QoS 1 引入了重传机制

当我们使用QoS 1 消息的时候,每个PUBLISH的报文,都必须有一个接收端的PUBACK的报文作为响应,以确认接收对收到了消息,如果一直没有响应,发送端就会在特定时刻重新发送没有响应的消息,在PUBLISH中需要有Packet ID字段来作为该消息的唯一标识,而PUBACK响应中,也会包含收到消息相同的Packet ID,这样发送端在收到PUBACK报文时,就可以确认是哪条消息到达了

通过QoS 1 的重传机制,我们可以保证消息到达了,但是也不可能避免有了消息重复的可能性

当发送端因为没有收到响应报文重传的时候,可能接收端已经收到了消息并且回复了响应报文,但是响应报文可能因为网络断开等其他原因丢失了,这种情况下发送端再发送消息,接收端就收到了重复消息,虽然发送端在重传发送消息的时候会把DUP设置为1表示这是重传的消息,但是接收端也不能确定自己层级是否接受过该消息,会把消息当全新消息处理

如何为QoS 1 去重

虽然在协议层面我们没办法避免消息的重复,但是可以从业务的层面入手对消息进行去重,一个简单的方法是在每个PUBLISH报文的payload中携带一个时间戳或者单调递增的计数,这样业务层就可以根据时间戳或者计数是否大于上一次收到消息的时间戳or技术,来判断是不是新消息

重传不等于乱序

虽然发生了重传,但是不表示消息会乱序到达,我们发送了A、B、C三条消息,如果是A重传,就是 A、A、B、C ,如果A、B重传,就是A、B、A、B、C等等,不可能出现B、A、C这种情况

QoS 2

仅交付一次,消息不会重复也不会丢失,QoS 2也有这三种模式最复杂的报文交互,想要完成QoS 2的消息传递,最少要完成两次的请求响应流程,带来额外的性能开销

QoS2的报文

  • PUBLISH

    发布报文

  • PUBREC

    PUBLISH和RECEIVE的缩写,表示收到了PUBLISH报文

  • PUBREL

    PUBLISH 和RELEASE的缩写,表示准备释放这次的QoS2消息

  • PUBCOMP

    PUBLISH和COMPLETE的缩写,表示这一次QoS2的消息的发布即将完成

为什么QoS2的报文不会重复

​ QOS 2 使用PUBLISH和PUBREC报文来保证消息的到达,原理和QoS1一致,新增的PUBREL和PUBCOMP来保证消息不会重复,QoS2规定,发送端只有在收到PUBREC报文之前,才可以重传PUBLISH报文,而一旦收到了PUBREC报文并且发出了PUBREL报文,发送端就进入了Packet ID的释放流程,在收到接收端的PUBCOMP响应之前,发送端既不会使用该Packet ID重传消息,也不能用于发布新的消息,只有收到PUBCOMP响应之后,发送端才可以继续使用这个Packet ID,对于接收端来说,可以以PUBREL为界限,凡是PUBREL之前到达的PUBLISH报文,必然是重复的消息,PUBREL之后到达的消息,全是全新的消息

分发QoS2的消息

​ 如果接收端必须等到QoS2流程结束才能向后分发消息,如果网络不好的情况下,消息的实时性会受到很大影响,所以MQTT允许接收端第一次收到PUBLISH报文的时候,就启动消息的向后分发,一旦分发过之后,后续再收到重传报文,接收端就不能再进行分发操作了,以免消息操作

何时重传消息

​ 在QoS0和Qos1中,都有可能存在消息的重传,这里的重传并不是指超时的重传,在TPC连接内重传消息,并不会带来额外的收益,在网络不佳的情况下,反而可能降低消息的传输效率,也可能导致报文的收发流程异常,所以MQTT要求,只有在每次连接断开重连后,发送端才能重传上一次连接内没有收到响应的消息

不同的QoS的适用场景

QoS 0
  • 优点:投递效率高
  • 缺点:消息可能丢失
  • 适用场景:传输高频且不是那么重要的数据
QoS 1
  • 优点:保证消息到达
  • 缺点:消息可能重复
  • 适用场景:传输较为重要的数据,需要注意业务需要能够处理重复消息,或者能够允许重复消息
QoS 2
  • 优点:保证消息到达且不会重复
  • 缺点:拥有较高的开销
  • 适用场景:传输重要数据,并且能够接受QoS 2带来的额外的开销

MQTT-QoS与协议流程的更多相关文章

  1. MQTT QoS 0, 1, 2 介绍

    什么是 QoS 很多时候,使用 MQTT 协议的设备都运行在网络受限的环境下,而只依靠底层的 TCP 传输协议,并不能完全保证消息的可靠到达.因此,MQTT 提供了 QoS 机制,其核心是设计了多种消 ...

  2. MQTT 3.1协议非严肃反思录

    前言 MQTT 3.1协议在弱网络环境下(比如2G/3G等)表现不够好,因此才有了反思. 弱网环境下表现 手机等终端在弱网络环境下丢包情况会非常明显,连接MQTT Server成功率很低.相比单纯的请 ...

  3. CoAP、MQTT、RESTful协议区别

    /********************************************************************** * CoAP.MQTT.RESTful协议区别 * 说明 ...

  4. mqtt Qos

    mqtt Qos QoS Level 0:至多一次意思就是给你转发一次就得了,不管你有没收到.这个我理解是如果接收方离线了就不能收到消息,可以用在音视频聊天请求,因为当接收方离线后就不用收到请求了,就 ...

  5. jmeter如何进行MQTT性能测试(测试前期准备二,MQTT插件及协议了解)

    jmeter插件下载地址及使用,已经有大佬总结好了 大佬的博客地址: https://blog.csdn.net/yellowanwu/article/details/50889677 添加线程组:添 ...

  6. MQTT 简介及协议原理

    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种构建于TCP/IP协议上基于发布/订阅(publish/subscribe)模式的“轻量 ...

  7. MQTT物联网通讯协议入门

    目录 一.MQTT协议概念 发布/订阅机制 MQTT客户端 Broker代理(服务器) MQTT消息结构 二.MQTT协议实现原理 MQTT连接 MQTT消息发布 MQTT订阅机制 MQTT订阅确认 ...

  8. EasyRTMP实现的rtmp推流的基本协议流程

    EasyRTMP介绍 EasyRTMP是结合了多种音视频缓存及网络技术的一个rtmp直播推流端,包括:圆形缓冲区(circular buffer).智能丢帧.自动重连.rtmp协议等等多种技术,能够非 ...

  9. 关于Kerberos协议流程的总结

    Kerberos协议工作原理分析 这里面借用一下师傅们的图来说明一下    Kerberos协议的流程大致如下(假设A要获取对Server B的访问权限) 第一步(KRB_AS_REQ) 这一步客户 ...

  10. 浅尝 ECDHE 协议流程

    前言 ECDHE 我之前是听都没听过, 但是新业务需要对前后端通信进行加密, 经过大佬推荐才知道有这个东西, 经过几天的学习和踩坑, 才大致明白其流程和使用方式. 过程坎坷, 好在最后还是成功运用到了 ...

随机推荐

  1. @JsonIgnore 失效没起作用及 @JSONField(serialize = false)

    项目中需要对接口返回的某一个字段进行屏蔽,返回给前端响应的时候,不显示某个字段. 第一时间想到在实体类屏蔽的属性字段上添加@JsonIgnore注解,但添加之后并没有起作用. 在网上搜索了下,使用 @ ...

  2. [python]使用标准库logging实现多进程安全的日志模块

    前言 原本应用的日志是全部输出到os的stdout,也就是控制台输出.因其它团队要求也要保留日志文件,便于他们用其他工具统一采集,另一方面还要保留控制台输出,便于出问题的时候自己直接看pod日志.具体 ...

  3. 2023第十四届极客大挑战 — CRYPTO(WP全)

    浅谈: 本次大挑战我们队伍也是取得了第一名的成绩,首先要感谢同伴的陪伴和帮助.在共同的努力下终不负期望! 但遗憾的是我们没有在某个方向全通关的,呜呜呜~ 继续努力吧!要学的还很多.明年有机会再战!!加 ...

  4. JMS微服务开发示例(八)双机热备

    双机热备,指两个一模一样的微服务,两个同时在运行,但是只有一个在工作,当工作中的微服务垮掉后,另一个会自行补上. 要实现这个,只需要设置 SingletonService = true. var mi ...

  5. solr-es

    一.lucene 1.是什么 是apache提供的一套java写的用于全文检索工具包,该工具包提供了用于实现全文检索的api类,可用于实现搜索引擎功能. 2.搜索常用方法 顺序扫描法:应用于数据结构固 ...

  6. [转帖]kafka-console-ui v1.0.6发布

    前言 kafka-console-ui 是一款web版的kafka管理平台,从第一次发布到现在已经两年了,断断续续也更新了7个版本了(v1.0.0~v1.0.6). 一些常用的功能也陆续完善了不少,相 ...

  7. [转帖]python库Paramiko

    https://zhuanlan.zhihu.com/p/456447145 测试过程中经常会遇到需要将本地的文件上传到远程服务器上,或者需要将服务器上的文件拉到本地进行操作,以前安静经常会用到xft ...

  8. [转帖]CentOS7完美升级gcc版本方法

    https://blog.whsir.com/post-4975.html 在某些应用场景中,需要特定的gcc版本支持,但是轻易不要去编译gcc.不要去编译gcc.不要去编译gcc,我这里推荐使用红帽 ...

  9. sringboot 调试端口启用的写法

    注意 需要在 -jar 的后面加 加在前面貌似没用 $JAVA_HOME/bin/java -Dloader.path=$CAF_MODULE_PATHS -jar -Dspring.profiles ...

  10. 随性翻译: Java的运行时参数简单总结

    Java的运行时参数简单总结 简单学习了下Oracle官方的资料: https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.ht ...