我的mqtt协议和emqttd开源项目个人理解(15) - MQTT消息推送协议应用数据包超时是否需要重发?

简介: 我的mqtt协议和emqttd开源项目个人理解(15) - MQTT消息推送协议应用数据包超时是否需要重发?

https://blog.csdn.net/libaineu2004/article/details/80493902



今天在看MQTT协议文档,到处关于QoS(Quality of Service)的介绍,文档说如果没有收到对方的PUBREL等确认包,超时后server需要'delivery retry", 一开始觉得理所当然的,重发嘛,丢包,正常。


然后就看到消息重发(Message delivery retry)这一章:


4.2. Message delivery retry


Although TCP normally guarantees delivery of packets, there are certain scenarios where an MQTT message may not be received. In the case of MQTT messages that expect a response (QoS >0 PUBLISH, PUBREL, SUBSCRIBE, UNSUBSCRIBE), if the response is not received within a certain time period, the sender may retry delivery. The sender should set the DUP flag on the message.


上面说TCP在某种情景下下可能会丢包,一想不对呀,TCP能够保证可靠传输的,当然send()不保证对方能收到,但是至少是“尽量能保证”对方能收到。而且是:要么对方应用程序全部收不到,要么就是按序收到数据的。


比如发出去了A包,但是A.ack回包没有收到,超时了。这个时候协议说,server需要"the sender may retry delivery",也就是重传一个A‘ 的第二个包。


不应呀,于是问了问朋友,对方也觉得不应该的,虽然说TCP也不是可靠传输,不一定能保证对方能收到。但它无论如何能够保证对方要么前面后面的都收不到,要么前面的肯定在后面的之前收到。所以这么说来,是不需要重传的。没有必要。


可能协议没有说清楚,也许指的是说客户端挂了,bug了,把消息在对方代码里面丢了,core了什么的。所以查了查邮件列表什么的。找到了一个今年8月份的讨论,总算找到了原因,是文档没有写清楚,目前最新文档时3.1版本,邮件组里面说3.1.1版本已经修改了描述,但还没有发出来。


真正的重发只需要存在于连接出问题断开的情况,比如客户端重连了,而且上次断开之前没有叫我clean session,那server需要重发上次的数据,其实就等于是要补发离线记录一个道理。另外如果有老版本的TCP协议客户端存在,其不支持可靠传输,也需要重发。具体可以看这里的总结,大概的结论是:


1.只要连接没有断开,不需要重传;


2.协议这么写是为了兼容老版的TCP/IP协议,可能那些协议可能有丢包(到达应用层的丢包,不指IP层);


3. 在3.1.1版已修改了表述。




TCP/IP的超时与重传使用的是“指数退避”的方式。分别为1、3、6、12、24、48和多个64秒。首次分组传输与复位信号传输之间的时间差约为9分钟。


第一次发送后所设置的超时时间实际上为1.5秒,此后该时间在每次重传时增加一倍,一直到64秒,采用的是指数退避算法。一共重传12次,大约9分钟才放弃重传,该时间在目前的TCP实现中是不可变的,Solaris2.2允许管理者改变这个时间,tcp_ip_abort_interval变量。且其默认值为两分钟,而不是最常用的9分钟。


相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
3月前
|
消息中间件 存储 监控
搭建消息时光机:深入探究RabbitMQ_recent_history_exchange在Spring Boot中的应用【RabbitMQ实战 二】
搭建消息时光机:深入探究RabbitMQ_recent_history_exchange在Spring Boot中的应用【RabbitMQ实战 二】
34 1
|
3月前
|
传感器 网络协议 物联网
在Linux中搭建Mosquitto MQTT协议消息服务端并结合内网穿透工具实现公网访问
Mosquitto是一个开源的消息代理,它实现了MQTT协议版本3.1和3.1.1。它可以在不同的平台上运行,包括Windows、Linux、macOS等。mosquitto可以用于物联网、传感器、移动应用程序等场景,提供了一种轻量级的、可靠的、基于发布/订阅模式的消息传递机制。
|
3月前
|
网络协议 Go 数据安全/隐私保护
golang开源的可嵌入应用程序高性能的MQTT服务
golang开源的可嵌入应用程序高性能的MQTT服务
253 2
|
2月前
|
监控 网络性能优化 网络安全
【MODBUS】Modbus主站为边缘设备通过MQTT协议上云
【MODBUS】Modbus主站为边缘设备通过MQTT协议上云
34 1
|
3月前
|
物联网 Linux 开发工具
MQTT协议接入问题之连接失败如何解决
MQTT接入是指将设备或应用通过MQTT协议接入到消息服务器,以实现数据的发布和订阅;本合集着眼于MQTT接入的流程、配置指导以及常见接入问题的解决方法,帮助用户实现稳定可靠的消息交换。
144 2
|
3月前
|
JSON 物联网 开发工具
MQTT协议问题之如何搭建物联网空调的服务器
MQTT协议是一个轻量级的消息传输协议,设计用于物联网(IoT)环境中设备间的通信;本合集将详细阐述MQTT协议的基本原理、特性以及各种实际应用场景,供用户学习和参考。
79 1
|
3月前
|
JSON 网络协议 物联网
MQTT协议问题之消息类型分类如何解决
MQTT协议是一个轻量级的消息传输协议,设计用于物联网(IoT)环境中设备间的通信;本合集将详细阐述MQTT协议的基本原理、特性以及各种实际应用场景,供用户学习和参考。
49 3
|
3月前
|
消息中间件 网络协议 物联网
MQTT协议问题之阿里云物联网服务器断开如何解决
MQTT协议是一个轻量级的消息传输协议,设计用于物联网(IoT)环境中设备间的通信;本合集将详细阐述MQTT协议的基本原理、特性以及各种实际应用场景,供用户学习和参考。
135 1
|
3月前
|
存储 监控 物联网
MQTT协议问题之OTA升级包下载如何解决
MQTT协议是一个轻量级的消息传输协议,设计用于物联网(IoT)环境中设备间的通信;本合集将详细阐述MQTT协议的基本原理、特性以及各种实际应用场景,供用户学习和参考。
113 3
|
3月前
|
消息中间件 Web App开发 监控
mqtt数据问题之如何实现webRTC 协议的监控视频压测
MQTT协议是一个轻量级的消息传输协议,设计用于物联网(IoT)环境中设备间的通信;本合集将详细阐述MQTT协议的基本原理、特性以及各种实际应用场景,供用户学习和参考。
64 0