MQTT之重复消息(5、TCP重连和MQTT重连)

news2025/4/1 2:49:49

目录

1. TCP 协议层的重传(原生机制)

2. 触发 TCP 重传的具体场景

3、TCP 重传的关键参数(了解)

第一、重传超时(RTO - Retransmission Timeout)

第二、重传次数

第三、累计时间 vs 本次 RTO 的区别

第四.常见问题解答

第五.总结

4、MQTT 重发机制和TCP重发机制对比

5、MQTT关键超时时间设置(Springboot)

1. 连接超时(Connect Timeout)

2. 操作超时(Completion Timeout)

3. Keepalive间隔

4. 自动重连配置

5. 配置原则

6.典型场景配置示例

7.监控与调优建议

1. TCP 协议层的重传(原生机制)

TCP协议本身自带的可靠性机制,而不是 MQTT 协议实现,他是传输层(第4层)的内置功能:

  • 完全由操作系统实现:Linux/Windows 等操作系统的 TCP/IP 协议栈实现

  • 与上层协议无关:对 HTTP、MQTT、FTP 等所有基于 TCP 的应用层协议透明

  • 核心保障机制

    • 超时重传(RTO)

    • 快速重传(收到3个重复ACK时触发)

    • 选择性确认(SACK)

2. 触发 TCP 重传的具体场景

第一、数据包丢失

  • 网络拥塞导致路由器丢弃数据包

  • 物理链路问题导致传输失败

第二、确认包(ACK)丢失

  • 接收方已收到数据但 ACK 丢失

  • 发送方未收到 ACK 触发重传

第三、 网络延迟

  • 往返时间(RTT)超过重传超时(RTO)阈值

  • 突发性网络延迟导致误判

3、TCP 重传的关键参数(了解)

        在 Spring Boot 应用中,虽然不能直接设置 TCP 重传超时(RTO)和重传次数等底层参数(这些通常由操作系统内核管理),但可以通过以下几种方式间接影响或了解这些 TCP 行为:

第一、重传超时(RTO - Retransmission Timeout)

        TCP 重传的时间取决于 RTO(Retransmission Timeout) 的动态计算,并采用 指数退避(Exponential Backoff) 机制逐步增加重传间隔。以下是详细分析:

  • 动态计算的值,基于 RTT 测量

  • 典型初始值:1秒(Linux 默认)

  • 计算公式:RTO = SRTT + max(G, K×RTTVAR)

    • SRTT: 平滑的 RTT 估计值

    • RTTVAR: RTT 变化量

    • G: 时钟粒度

    • K: 通常为4

  • 1. 系统默认参数

  • 初始 RTO = 1 秒(1000ms)

  • 最小 RTOtcp_rto_min)= 200ms

  • 最大 RTOtcp_rto_max)= 120 秒

  • 最大重传次数tcp_retries2)= 15 次

  • 指数退避规则:每次重传的 RTO = min(2的n−1次方×初始 RTO, tcp_rto_max)

# 查看当前配置
cat /proc/sys/net/ipv4/tcp_retries2     # 最大重传次数(默认15)
cat /proc/sys/net/ipv4/tcp_rto_min      # 最小RTO(默认200ms)
cat /proc/sys/net/ipv4/tcp_rto_max      # 最大RTO(默认120s)

# 修改配置(临时)
echo 8 > /proc/sys/net/ipv4/tcp_retries2     # 减少重传次数
echo 1000 > /proc/sys/net/ipv4/tcp_rto_min   # 设置最小RTO=1s

第二、重传次数

  • 系统级配置(如 Linux 的 /proc/sys/net/ipv4/tcp_retries2)

  • 典型默认值:15次

  • 总重传时间可达数分钟

从第一次重传开始,每次 RTO 按指数退避增长,直到达到 tcp_rto_max 或重传 15 次。

重传次数 (n)本次 RTO累计时间计算公式
11.0s1.0s初始 RTO
22.0s3.0s (1+2)1.0 × 2
34.0s7.0s (3+4)2.0 × 2
48.0s15.0s (7+8)4.0 × 2
516.0s31.0s (15+16)8.0 × 2
632.0s63.0s (31+32)16.0 × 2
764.0s127.0s (63+64)32.0 × 2
8120.0s247.0s (127+120)min(64×2, 120) → 120s
9120.0s367.0s (247+120)已达上限,不再增加
............
15120.0s累计 924.0s15.4 分钟

第三、累计时间 vs 本次 RTO 的区别

1. 本次 RTO(Retransmission Timeout)

  • 定义当前这一次重传需要等待的时间(从发送数据包到触发重传的间隔)。

  • 动态计算:基于公式 RTO = SRTT + max(G, K×RTTVAR),并受指数退避规则影响。

  • 关键点

    • 每次重传的 RTO 是独立的等待时间。

    • 例如:第一次重传 RTO=1s,第二次 RTO=2s,第三次 RTO=4s,依此类推。

2. 累计时间

  • 定义从首次发送数据包到当前重传时刻的总耗时(包括之前所有重传的等待时间)。

  • 计算方式:累加所有已发生的 RTO 值。

  • 关键点

    • 反映的是从第一次发送到当前重传的总延迟。

    • 例如:第三次重传时,累计时间 = 第一次 RTO(1s) + 第二次 RTO(2s) + 第三次 RTO(4s) = 7s。


3.具体实例对比

        假设初始 RTO=1s,tcp_retries2=3

重传次数

本次 RTO

累计时间

说明

1

1s

1s

第一次重传,等待 1s

2

2s

1s + 2s = 3s

第二次重传,再等 2s(总 3s)

3

4s

3s + 4s = 7s

第三次重传,再等 4s(总 7s)

  • 本次 RTO:每次重传的独立等待时间(如第三次重传的 RTO=4s)。

  • 累计时间:从开始到当前的总时间(如第三次重传时累计已等待 7s)。

第四.常见问题解答

Q1: 为什么累计时间不是简单的 RTO 相加?

  • 因为 RTO 是动态计算的,每次重传的 RTO 可能不同(受网络波动影响),但默认情况下按指数退避增长(×2)。

Q2: 应用层超时应参考哪个时间?

  • 必须参考累计时间
    例如:若 tcp_retries2=15,累计时间可能达 924s,应用层超时应设置为 大于 924s,否则会提前误判超时。

Q3: 如何验证实际 RTO 和累计时间?

# 查看实时 TCP 连接的 RTO
ss -ti | grep "rto:"
# 输出示例:rto:204 rtt:1.875/0.75 (当前 RTO=204ms)

# 统计历史重传次数(间接反映累计时间)
netstat -s | grep "segments retransmitted"

第五.总结

概念含义应用场景
本次 RTO当前重传需等待的时间调整 tcp_rto_min/max
累计时间从首次发送到当前的总耗时设置应用层超时(如 MQTT/HTTP)

理解这两个概念的区别,能帮助更精准地设计超时和重试策略。

4、MQTT 重发机制和TCP重发机制对比

        第一、核心区别

        TCP重连和MQTT重连是不同层次的机制,它们不是矛盾关系,也不是完全一回事,而是协同工作的互补机制。以下是详细对比分析

维度TCP重连MQTT重连
协议层传输层(L4)应用层(L7)
触发条件TCP连接中断(如网络断开)MQTT会话异常(如心跳超时)
重连内容重建TCP三次握手重建MQTT CONNECT会话
可见性操作系统自动处理,对应用透明需要应用层逻辑处理
恢复目标恢复字节流传输通道恢复MQTT会话状态

        第二、工作流程比对

        1、TCP重连流程(操作系统驱动)

graph LR
    A[网络中断] --> B{TCP Keepalive探测}
    B -->|超时| C[发送RST断开]
    D[应用尝试通信] --> E[触发系统级TCP重连]
    E -->|成功| F[重建TCP连接]
    E -->|失败| G[返回错误给应用层]

        2、MQTT重连流程(应用层驱动)
 

graph LR
    A[检测到连接异常] --> B{是否自动重连?}
    B -->|是| C[发送CONNECT报文]
    C --> D{携带CleanSession?}
    D -->|false| E[恢复原有会话]
    D -->|true| F[新建会话]
    B -->|否| G[通知应用程序]

        第三、协同工作场景示例

当网络出现问题时,两者的协作顺序:

  1. 断联

    • TCP层先尝试重连(内核自动完成)

    • 如果TCP重连成功,MQTT可能不会感知到中断

    • 如果TCP重连失败,MQTT感受到了链接中断,这个时候启动MQTT的重连机制(这就是重复消息的原因)

  2. 链接超时

    • 如果TCP的重连时间大于MQTT的响应时间,这个时候MQTT会重发消息(这就是重复消息的原因)

    • 如果TCP的重连时间小于MQTT的响应时间,MQTT可能不会感知到中断。

5、MQTT关键超时时间设置(Springboot)

        1. 连接超时(Connect Timeout)

// Paho客户端示例
MqttConnectOptions options = new MqttConnectOptions();
options.setConnectionTimeout(60); // 单位:秒

建议值

  • 参数setConnectionTimeout(60)

  • 单位:秒

  • 作用:客户端尝试与MQTT服务器建立TCP连接时的最大等待时间。

  • 示例
        假设你的设备在弱网环境下(如2G网络)连接云端MQTT服务器:

    • 如果服务器60秒内没有响应TCP握手,客户端会放弃连接并触发连接失败回调。

    • 典型场景:设备在信号差的地区启动时,避免因无限等待而卡死。

  • 至少30秒(覆盖TCP SYN重传)

  • 移动网络建议60-120秒

        2. 操作超时(Completion Timeout)

// Eclipse Paho配置
options.setCompletionTimeout(30000); // 单位:毫秒

建议值

  • 参数setCompletionTimeout(30000)

  • 单位:毫秒(30秒)

  • 作用:控制MQTT操作(如连接、订阅、发布)的完成等待时间。

  • 示例

    • 客户端发布一条QoS=1的消息(需要服务端确认):

      • 如果30秒内未收到服务端的PUBACK确认,客户端会判定操作超时,可能触发重发或错误回调。

    • 典型场景:防止因网络延迟或服务器繁忙导致客户端长期阻塞。

  • 大于TCP最大重传时间(通常设置30-120秒)

        3. Keepalive间隔

options.setKeepAliveInterval(60); // 单位:秒

  • 参数setKeepAliveInterval(60)

  • 单位:秒

  • 作用:客户端定期发送PING请求(心跳包)以维持连接的间隔时间。

  • 示例

    • 客户端与服务端建立连接后,如果60秒内没有数据交互:

      • 客户端会自动发送一个PING请求,服务端必须响应PONG。

      • 如果未收到PONG,客户端会认为连接已断开,触发重连机制。

    • 典型场景:检测设备突然掉线(如断电或进入隧道)。

建议值

  • 通常30-120秒

  • 应小于服务端的连接超时设置

        4. 自动重连配置

  • 参数setAutomaticReconnect(true)

  • 作用:连接断开时是否自动尝试重新连接。

  • 示例

    • 设备因网络波动断开MQTT连接后:

      • 客户端会在后台按指数退避策略(初始延迟短,逐渐增加)尝试重连。

      • 无需人工干预,适合IoT设备长期在线需求。

options.setAutomaticReconnect(true);

   5.  最大重连间隔

  • 参数setMaxReconnectDelay(30000)

  • 单位:毫秒(30秒)

  • 作用:限制自动重连时的最大等待间隔,避免无限制延长。

  • 示例

    • 第一次重连失败后,客户端可能等待1秒再次尝试;

    • 多次失败后,延迟时间会逐渐增加(如2秒、4秒、8秒…),但不会超过30秒。

    • 典型场景:避免服务器宕机时,设备因重连间隔过长(如几小时)无法及时恢复。

options.setMaxReconnectDelay(30000); // 最大重连间隔

   6. 配置原则

  1. 层级关系

       MQTT超时 > TCP最大重传时间 > 应用业务超时
  2. 网络类型调整

    • 稳定有线网络:可设置较小超时(30-60秒)

    • 移动/不稳定网络:建议120秒或更长

  3. 服务端协调

    • MQTT broker的连接超时应大于客户端设置

    • Will Message延迟应大于超时设置

7.典型场景配置示例

MqttConnectOptions options = new MqttConnectOptions();
options.setConnectionTimeout(120); // 2分钟连接超时
options.setKeepAliveInterval(90);  // 1.5分钟心跳
options.setCompletionTimeout(90000); // 1.5分钟操作超时
options.setAutomaticReconnect(true);
options.setMaxReconnectDelay(30000); // 30秒最大重连间隔

8.监控与调优建议

  1. 使用Wireshark或tcpdump监控实际TCP重传行为

  2. 根据网络质量动态调整超时参数

  3. 实现重试退避算法,避免频繁重连

        通过合理配置这些参数,可以确保MQTT客户端在网络波动时保持稳定,同时不会过早放弃有效的连接尝试。

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

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

相关文章

Github Webhook 以及主动式

Github配置 GitHub 默认支持两种 Content-Type: application/json application/x-www-form-urlencoded 特别要注意 Content-Type 我们选择: application/json Flask代码 import os import shutil import subprocess from flask import Flask, request, jsonifyapp = Fla…

猜猜我用的是哪个大模型?我的世界游戏界面简单的模拟效果

我的罗里吧嗦的,根据小朋友的要求,边听边写边输入的提示词: 请生成一段完整的在网页中用html5和javascript代码模拟“我的世界”中游戏场景的互动画面,要求提供若干人物选项可以选择,请自行选择需要使用哪些库或框架来…

基于龙芯3A5000处理器,全国产标准6U VPX板卡解决方案

1,产品功能 本产品为一款高可靠性的基于龙芯3A5000处理器以及 7A2000芯片组的标准6U VPX板卡,具有以太网、SATA、PCIE,以及显示等接口,产品功能框图如图1所示: 图1 系统框图 2,技术指标 序号 项目 指标…

Unity编辑器功能及拓展(3) —[Attribute]特性

在 Unity 中,[Attribute]格式的特性是用于扩展编辑器功能、控制序列化行为和调整 Inspector 显示,进行编辑器拓展的核心工具。 一.基础编辑器拓展 1.基础序列化控制 1.[SerializeField] 强制显示私有变量到Inspector 2.[HideInInspector] 隐藏该字段在Inspect…

HarmonyOS NEXT——鸿蒙神策埋点(二)

在上一章我分享了鸿蒙客户端集成神策埋点sdk的过程,现在我们需要服务端的小伙伴配置集成服务端sdk接收处理数据信息,以下是集成的过程。 Java服务端sdk集成 1、获取神策数据平台url地址 1、导入集成: dependencies {compile com.sensorsda…

编程考古-Borland JBuilder:一场关于Java灵魂的战争与救赎

本文也是填之前一位网友让谈谈JBuilder的一个坑,感谢各位技术爱好者的支持。感谢关注小编,你的关注,是我更新的动力。 本篇章节如下: 序章:JBuilder的黄金时代 Borland的JBuilder:纯技术主义的胜利 生死…

【day4】数据结构刷题 树

6-1 二叉树的遍历 函数接口定义: void InorderTraversal( BinTree BT ); void PreorderTraversal( BinTree BT ); void PostorderTraversal( BinTree BT ); void LevelorderTraversal( BinTree BT ); 其中BinTree结构定义如下: typedef struct TNode *Po…

Elea AI:以人工智能之力推动病理实验室革新的技术突破与实践探索

Elea AI:以人工智能之力推动病理实验室革新的技术分析 一、病理实验室现状与 Elea AI 的革新契机 (一)传统病理实验室的痛点剖析 在医疗体系中,病理实验室扮演着至关重要的角色,其诊断结果是疾病确诊与后续治疗方案制定的关键依据。然而,当前传统病理实验室在实际运作过…

相似度计算 ccf-csp 2024-2-2

#include<bits/stdc.h> using namespace std;int main() {// 定义两个变量 n 和 m&#xff0c;分别用于存储两篇文章的单词个数int n, m;// 从标准输入读取 n 和 m 的值cin >> n >> m;// 定义三个 map 容器&#xff0c;A 用于存储并集&#xff0c;T 用于标记…

多省发布!第27届中国机器人及人工智能大赛各赛区比赛通知

01 大赛介绍 中国机器人及人工智能大赛是由中国人工智能学会主办的极具影响力的全国性学科竞赛&#xff0c;旨在推动我国机器人及人工智能技术的创新与应用&#xff0c;促进相关专业的人才培养。作为全国高校学科竞赛A类赛事&#xff0c;该比赛吸引了众多高校和科研机构的积极…

对锁进行封装

目录 锁的封装 makefile编写 测试运行 RAII式封装 我们今天学习对锁进行封装。 我们在命名空间里面&#xff0c;在自己构建的类mutex里面完成对锁的封装。 锁的封装 我们要进行动态初始化锁&#xff0c;首先要有一个锁对象&#xff0c;所以mutex类里面的私有成员就是锁对…

C++Primer学习(14.1 基本概念)

当运算符作用于类类型的运算对象时&#xff0c;可以通过运算符重载重新定义该运算符的含义。明智地使用运算符重载能令我们的程序更易于编写和阅读。举个例子&#xff0c;因为在Sales_item类中定义了输入、输出和加法运算符&#xff0c;所以可以通过下述形式输出两个Sales_item…

HTML跑酷

先看效果 再上代码 <!DOCTYPE html> <html> <head><title>火柴人跑酷</title><style>body {margin: 0;overflow: hidden;background: #87CEEB;}#gameCanvas {background: linear-gradient(to bottom, #87CEEB 0%, #87CEEB 50%, #228B22 …

ChemBioServer: 一个在线“药物发现/再利用”的平台

ChemBioServer 是一个提供高级化学化合物过滤、聚类和网络分析的服务器&#xff0c;旨在支持药物发现和药物再利用&#xff08;drug repurposing&#xff09;。它集成了多种工具和网络服务&#xff0c;以便更高效地筛选、分析和可视化化学化合物。 网站地址&#xff1a; https:…

数据结构(4)——带哨兵位循环双向链表

目录 前言 一、带哨兵的循环双向链表是什么 二、链表的实现 2.1规定结构体 2.2创建节点 2.3初始化 2.4打印 2.5检验是否为空 2.6销毁链表 2.7尾插 2.8尾删 2.9头插 2.10头删 2.11寻找特定节点 2.12任意位置插入&#xff08;pos前&#xff09; 2.13删除任意节点 …

【MyBatis】MyBatis 操作数据库(入门)

文章目录 前言一、什么是MyBatis&#xff1f;二、MyBatis入门2.1、准备工作2.1.1 创建工程2.1.2、数据准备 2.2、配置数据库连接字符串2.3、写持久层代码2.4 单元测试 三、MyBatis的基础操作3.1 打印日志3.2、参数传递3.3、增(Insert)3.4、 删(Delete)3.5、改(Update)3.6、查(S…

高速电路中的存储器应用与设计四

5 SRAM介绍及其应用要点 DRAM的性能在很大程度上受到刷新操作的影响&#xff0c;而SRAM则不涉及刷新&#xff0c;因此在相同时钟频率的条件下&#xff0c;SRAM的性能远高于DRAM。 SRAM的缺点是集成度低、容量小、功耗大、价格高。 在应用的场合上&#xff0c;SRAM毫不逊色于…

Vue2 项目将网页内容转换为图片并保存到本地

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

HT81697——30W内置升压单声道D类/AB类音频功放

1 特性 ● 防削顶失真功能(防破音,Anti-Clipping Function,ACF) ● 扩频技术 ● 输出功率 28W (VBAT7.2V, RL4Ω, THDN10%, PVDD 15.5V, fiN 1kHz) 22W (VBAT7.2V,RL4Ω, THDN1%, PVDD 15.5V, fin 1kHz) 16.5W (VBAT3.7V, RL4Ω, THDN10%, PVDD 12V, fiN 1kHz) 12.8W (VBAT…

关于ArcGIS中加载影像数据,符号系统中渲染参数的解析

今天遇到一个很有意思的问题&#xff0c;故记录下来&#xff0c;以作参考和后续的研究。欢迎随时沟通交流。如果表达错误或误导&#xff0c;请各位指正。 正文 当我们拿到一幅成果影像数据的时候&#xff0c;在不同的GIS软件中会有不同效果呈现&#xff0c;但这其实是影像是…