MQTT中QOS级别

news2024/11/25 5:47:11

MQTT(Message Queuing Telemetry Transport)是一种轻量级的通信协议,在物联网和消息传递系统中广泛应用。MQTT 提供了三个不同的 QoS(Quality of Service)等级,用于确保消息的可靠性和传输效率。本文将详细介绍 MQTT 的 QoS 等级之间的区别,包括各自的特点、适用场景和性能表现。
消息质量:QoS 0 低 < QoS 1中 < QoS 2高

QoS 0:最多一次交付

QoS 0 是 MQTT 中最简单的交付等级。在 QoS 0 下,消息发布后,对消息的投递没有任何确认或重传机制。这意味着消息可能会有丢失或传输失败的风险。

  • 最多一次交付:消息发布后,至多会被传递一次,但不保证被成功接收。
  • 无需确认或重传:不会花费额外的网络传输或处理开销。
  • 低延迟:由于没有确认和重传机制,消息传输速度更快。

QoS 0 适用于以下场景:

  • 无需保证消息可靠性的应用场景,例如天气预报、传感器数据等。
  • 带宽受限的网络环境,因为 QoS 0 不会产生额外的网络传输开销。

QoS 1:至少一次交付

QoS 1 是 MQTT 中的中等交付等级。在 QoS 1 下,消息发布后,至少会被传递一次,但可能存在重复传递的情况。

  • 至少一次交付:消息发布后,将确保至少被传递一次,但可能会多次传递。
  • 确认和重传:如果消息未能成功传递给订阅者,MQTT 客户端会进行确认和重传处理。
  • 可靠性较高:相对于 QoS 0,QoS 1 提供了更高的消息传输可靠性。

QoS 1 适用于以下场景:

  • 需要确保消息至少被传递一次的应用场景,例如传感器数据采集、远程控制等。
  • 带宽充足的网络环境,因为 QoS 1 需要进行确认和重传,会产生一定的网络传输开销。

为什么QoS 1无法避免接收到重复消息?

当我们使用QOS1的时候,在pub ack包发送之后无论ack包是否到达发布者,PacketID都会被复用,也就说订阅者无法判断收到具有相同PacketID的消息是由于发布者未收到ACK报文进行的重传,还是复用之前的PacketID发送的新消息,这就是QoS1无法避免收到重复消息的原因。

QoS 2:只有一次交付

QoS 2 是 MQTT 中最高的交付等级。在 QoS 2 下,消息发布后,只会被传递一次,不会发生重复传递的情况。

  • 只有一次交付:消息发布后,将确保仅被传递一次,不会发生重复传递。
  • 确认和重传:如果消息未能成功传递给订阅者,MQTT 客户端会进行确认和重传处理,直到消息被接收为止。
  • 最高可靠性:相对于 QoS 0 和 QoS 1,QoS 2 提供了最高的消息传输可靠性。

QoS 2 适用于以下场景:

  • 需要确保消息仅被传递一次的关键应用场景,例如金融交易、远程医疗等。
  • 带宽充足的网络环境,因为 QoS 2 需要进行确认和重传,会产生较大的网络传输开销。

四次交互在三次交互基础上增加了一个pubcomp包,当publiser与server收到pubcomp包后,表示接收端已经收到release包了,因此可以删除msg了。到此,QOS=2实现了包的去重与msgid的可重用。

为什么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报文的时候,就启动消息的向后分发,一旦分发过之后,后续再受到重传报文,接收端就不能再进行分发操作了。

MQTT头中重要的标志位

message ID

只有当QoS等级是1或2时,报文标识符(Packet Identifier)字段才能出现在PUBLISH报文中。

消息ID用16位无符号整数来表示,在同一个方向上的在传消息ID必须是唯一的。它通常是逐个消息递增的,但不强制如此。

客户端与它所连接的服务器一样,都需要维护自己的消息ID列表,二者的消息ID列表互不影响。客户端在发送一个消息ID为1的 PUBLISH 消息的同时也有可能收到来自服务器的消息ID为1的 PUBLISH 消息。

表示消息ID的2个字节的顺序为先 MSB,再 LSB(大端模式)。

不要使用值为0的消息ID。它是作为无效消息ID保留的。 

一个消息ID用来匹配一个消息的交互确认,在QOS=1时用于标识一对报文,QOS=2时用于标识4个报文,即一个完整的消息通信及确认。

只有两次包交互看似已经完成了Exactly once delivery,但是subscribe端没有释放messageId,因为subscriber端不知道server是否收到subscriber发出的ack消息,所以需要一直保存msg或者msgId,来对server端超时重发的msg去重。而我们看到messageID的设计只有2个字节长度,也就是65535个,如果subscribe一直不删除本地messageID,那第二轮的messageID会冲掉第一轮的messageID,因此必须释放本地messageID。为什么把messageID设计的这么小呢,因为MQTT就是为那些小的硬件设备设计的,他们没有足够的内存与磁盘保存海量的msg。从上面可以看出来,两次交互不够,至少还需要一次交互告诉subscriber删除本地msg。对于server端也是如此,server也需要一直保存msg来防止publisher重发。

Retained

For QoS > 1, the message expiry interval dictates how long the retained message is kept.
However, it is important that the Broker avoids sending messages indefnitely for the Clients that
never update their tokens (i.e., the Client connects briefy with a valid token, sends a PUBLISH
packet with the RETAIN fag set to 1 and QoS > 1, disconnects, and never connects again).
Therefore, the Broker use the minimum of the token expiry and message expiry interval to
discard a retained message.
目前我们订阅时的QOS lever为2,发布时的QOS level 为0:
发布的时候Retain标志位为0,表示需要broker保存此topic的消息。
当生产者发布在topic上一条消息,同时在把retained=1。尽管消费者订阅topic是在发布消息之后,但消费者还是能消费到topic最后一条消息。特别注意:MQTT Broker只会为每一个topic保存最近收到的一条retained=true的消息!也就是说,如果MQTT Broker上已经为某个topic保存了一条retained消息,当生产者再次往该topic发布一条新的retained=true的消息,那么MQTT Broker上原来的那条消息会被覆盖。
一个新的消费者订阅多个topic,Broker会检查每个匹配的主题名中是否有retained=1的消息,如果存在最近保留的消息,它必须被发送给这个订阅者。
如果客户端发给服务端的PUBLISH报文的保留标志位: retained= 0,服务端不能存储这个消息也不能移除或替换任何现存的保留消息。
如果客户端想让MQTT Broker删除某个topic下保存的retained=true消息,唯一的方法是向MQTT Broker发布一条retained=true的空消息。
即使生产者掉线了,消费者一旦上线即刻就能订阅生产者最后一条发布的消息。
特别注意:消息的RETAIN标志位与消息的QoS无关,即无论使用哪种级别的QoS,只要设置了RETAIN标志位为 true,那么MQTT服务器就会保存该条消息!

Clean session Flag

对于客户端:可在connect报文中设置clean session标志位,0表示不清理会话,1表示清理会话。若在CONNECT报文中设置cleansession为0,且服务器回复的CONNACK报文中的Session Present位为1,则表示当前连接将会复用服务器保存的会话。

对于服务端:根据客户端CONNECT报文中的CleanSession标志位,来决定是否保存此次连接中客户端所订阅的主题的记录,在客户端断开连接后,服务器还得保存后面往该主题发送的消息。

客户端的连接报文中,CleanSession标志位设置为0,服务端会保存此次客户端订阅的所有主题,连接断开后,仍然保存订阅的消息。在客户端下线后,如果服务端接收到这些主题的消息,服务器会保存这些主题的消息,在客户端上线后,再往客户端推送这些主题的消息。

Keep Alive

当服务器在Keep Alive时间的1.5倍以上时间未收到设备心跳包时,则认为设备已经掉线了。此时服务器将会向设备设置的遗嘱消息主题发送遗嘱消息内容。

设备通知MQTT服务器KeepAlive的时间值为60秒,则设备必须在90秒内向服务器发送心跳包或者进行一次数据通信,否则服务器认为设备掉线。并关闭对应的MQTT TCP连接信息。

Dup Flag

如果DUP标志被设置为0,表示这是客户端或服务端第一次请求发送这个PUBLISH报文。如果DUP标志被设置为1,表示这可能是一个早前报文请求的重发。
客户端或服务端请求重发一个PUBLISH报文时,必须将DUP标志设置为1。对于QoS 0的消息,DUP标志必须设置为0。

服务端发送PUBLISH报文给订阅者时,收到(入站)的PUBLISH报文的DUP标志的值不会被传播。发送(出站)的PUBLISH报文与收到(入站)的PUBLISH报文中的DUP标志是独立设置的,它的值必须单独的根据发送(出站)的PUBLISH报文是否是一个重发来确定。

Message Expiry Interval

消息过期间隔(Message Expiry Interval)标识符。

跟随其后的是四字节整数表示的消息过期间隔(Message Expiry Interval)。

如果消息过期间隔存在,四字节整数表示以秒为单位的应用消息(Application Message)生命周期。如果消息过期间隔(Message Expiry Interval)已过期,服务端还没开始向匹配的订阅者交付该消息,则服务端必须删除该订阅者的消息副本。

如果消息过期间隔不存在,应用消息不会过期。

服务端发送给客户端的PUBLISH报文中必须包含消息过期间隔,值为接收时间减去消息在服务端的等待时间

时间敏感性

 对于QOS=1或2时,分别有2个和4个报文交互,那么这些报文需要在多长时间内发送完成呢?一旦没有在规定的时间内完成,需要怎么处理呢?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1565809.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过SSH在苹果手机上查看系统文件:远程访问iOS文件系统的方法

​ 目录 引言 用户登录工具和连接设备 查看设备信息&#xff0c;电池信息 查看硬盘信息 硬件信息 查看 基带信息 销售信息 电脑可对手机应用程序批量操作 运行APP和查看APP日志 IPA包安装测试 注意事项 引言 苹果手机与安卓手机不同&#xff0c;无法直接访问系统文件…

游戏陪玩平台开发 定制专属陪玩平台-移交源码二次开发,线下可改陪诊,陪伴,家政等功能

线下陪玩接单服务软件系统搭建&#xff08;APP&#xff0c;h5小程序&#xff0c;公众号开发&#xff09;&#xff0c;陪玩接单服务小程序开发搭建&#xff0c;陪玩接单服务系统开发设计&#xff0c;陪玩接单服务软件开发制作&#xff0c;陪玩接单服务平台开发方案 随着人们生活…

记Postman参数化

因为需要在WEB页面上处理部分数据&#xff0c;手动操作太慢&#xff0c;所以考虑使用接口方式处理&#xff0c;因急于使用&#xff0c;用Python Request的方式&#xff0c;写代码也来得慢&#xff0c;故采用Postman加外部文件参数化方式来实现。 接口请求是Post方式&#xff0c…

流域生态系统水-碳-氮耦合过程模拟

原文链接&#xff1a;流域生态系统水-碳-氮耦合过程模拟https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247599933&idx1&sn64dd4dae8b54e7f2c4a18a2729f423d4&chksmfa8206dacdf58fcc4ff9cb95443bdbd238b0f38f0616bbe53c093f68c851f2526a82898c69d2&…

Bessie‘s Birthday Cake (Hard Version)

题目链接 CodeTON Round 8 (Div. 1 Div. 2, Rated, Prizes!) C2. Bessie’s Birthday Cake (Hard Version) 思路&#xff1a; 其实可以先做一下easy version。 先不选点&#xff0c;已有的点我们肯定能加多少边就加多少&#xff0c;而且手玩后发现一个规律&#xff0c;就是…

Lua环境下载与配置

这里介绍如何下载已经编译好的Lua环境&#xff0c;如何配置Lua环境。 如希望自己从源码编译Lua环境&#xff0c;请自行搜索资料。 第一步&#xff1a;下载编译好的lua环境 打开下面链接&#xff0c;然后根据指引下载。 The Programming Language Luahttps://www.lua.org/hom…

基于卷积神经网络的苹果等级分类系统(pytorch框架)【python源码+UI界面+前端界面+功能源码详解】

功能演示&#xff1a; 苹果等级分类系统&#xff0c;基于vgg16&#xff0c;resnet50卷积神经网络&#xff08;pytorch框架&#xff09;_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于卷积神经网络的苹果等级分类系统是在pytorch框架下实现的&#xff0c;系统中有两…

神经网络与深度学习(二)

一、深度学习平台 张量&#xff08;Tensor&#xff09; 是一个物理量&#xff0c;对高维(维数 ≥ 2) 的物理量进行“量纲分析” 的一种工具。简单的可以理解为&#xff1a;一维数组称为矢量&#xff0c;二维数组为二阶张量&#xff0c;三维数组为三阶张量 计算图 用“结点”…

03-Linear Regression

什么是回归算法 回归算法是一种有监督算法回归算法是一种比较常用的机器学习算法&#xff0c;用来建立“解释”变量(自变量X)和观测值 (因变量Y)之间的关系; 从机器学习的角度来讲&#xff0c;用于构建一个**算法模型(函数)**来做属性 ( X ) (X) (X) 与标签 ( Y ) (Y) (Y) 之…

Docker in Docker原理与实战探索

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

在 Windows 中安装部署并启动连接 MongoDB 7.x(命令行方式启动、配置文件方式启动、将启动命令安装为系统服务实现开机自启)

MongoDB 的下载 下载地址&#xff1a;https://www.mongodb.com/try/download/community 这里需要对 MongoDB 的版本号说明一下&#xff1a; MongoDB 版本号的命名规则是 x.y.z&#xff0c;当其中的 y 是奇数时表示当前的版本为开发版&#xff0c;当其中的 y 是偶数时表示当前的…

OpenHarmony实战开发-使用一次开发多端部署实现一多设置典型页面

介绍 本示例展示了设置应用的典型页面&#xff0c;其在小窗口和大窗口有不同的显示效果&#xff0c;体现一次开发、多端部署的能力。 1.本示例使用一次开发多端部署中介绍的自适应布局能力和响应式布局能力进行多设备&#xff08;或多窗口尺寸&#xff09;适配&#xff0c;保…

IDEA一键备份MySQL数据库(mysqldump版)

问题 又到了搬MySQL数据库的时刻&#xff0c;这次我不想使用命令行备份&#xff0c;这次我想使用IDEA一键备份MySQL数据库。 解决 假设安装好mysqldump命令后&#xff0c;让IDEA使用mysqldump一键备份指定的数据库。具体IDEA配置如下&#xff1a; 这是IDEA上面的数据库到处…

语音芯片 SOP8、SOP16、SOP24脚在性能上有哪些不同呢?

随着语音识别技术的不断发展&#xff0c;人们对语音芯片的需求也越来越高。 其中&#xff0c;SOP8、SOP16和SOP24脚语音芯片是目前市面上应用比较广泛的芯片类型。这些芯片在性能上有什么区别&#xff1f;下面我们来具体分析一下。 首先&#xff0c;SOP8、SOP16、SOP24脚语音芯…

基于单片机20v数字电压表仿真系统设计

**单片机设计介绍&#xff0c;基于单片机20v数字电压表仿真系统设计 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机20V数字电压表仿真系统设计的主要目标是实现一个能够准确测量和显示20V直流电压的仿真系统。以下是该设计的主…

Oracle数据库常见 问题 或 报错 集合

【报错】字段长度不足 一般字段长度不够时报错&#xff1a; Cause: java.sql.SQLException: ORA-12899: value too large for colum “列名” 【报错】修改字段长度&#xff0c;提示资源正忙 以pl/sql为例&#xff1a; ctrl选中表&#xff0c;在列选项卡下修改字段长度&#x…

Mac反编译APK

文章目录 第一种方式: brew installapktool 使用说明dex2jar 使用说明 第二种方式: 下载安装包apktool 使用说明 (根据官方介绍没有操作成功,后续成功再更新这里)dex2jar 使用说明 安装 JD-GUI 查看jar包中的class文件JD-GUI 使用说明 第一种方式: brew install 安装过程可能很…

【测试篇】测试分类

文章目录 测试分类的框架按照测试对象划分(一) 可靠性测试(二) 容错性测试(三) 安装卸载测试(四) 内存泄露测试(五) 弱网测试(六) 文档测试 按是否查看代码(一) 黑盒测试(二) 白盒测试(三) 灰盒测试 按开发阶段划分(一) 单元测试(二) 集成测试(三) 系统测试(四) 回归测试(五) 冒…

IoT数采平台1:开篇

IoT数采平台1&#xff1a;开篇IoT数采平台2&#xff1a;文档IoT数采平台3&#xff1a;功能IoT数采平台4&#xff1a;测试 【功能概述】 开箱即用; 向下接入不同设备(PLC / 采集网关 / OPC / TCP设备 / UDP设备 / HTTP接入),向上通过MQTT发布消息; 数采底层基于NET CORE,既支持P…

3.恒定乘积自动做市商算法及代码

中心化交易所的安全风险 在中心化交易所中注册账户时&#xff0c;是由交易所生成一个地址&#xff0c;用户可以向地址充币&#xff0c;充到地址之后交易所就会根据用户充币的数量显示在管理界面中。但是充币的地址是掌管在交易所之中的&#xff0c;资产的控制权还是在交易所。…