Netty——连接超时 与 断开重连

文章目录

  • 1. 处理连接超时和断开重连的原因
  • 2. 处理连接超时和断开重连的方法
    • 2.1 处理连接超时
      • 2.1.1 步骤一:配置连接超时时间
      • 2.1.2 步骤二:监听连接结果
    • 2.2 处理断开重连
      • 2.2.1 步骤一:监听连接断开事件
      • 2.2.2 步骤二:实现重连逻辑
        • 指数退避策略
          • 1. 指数退避策略的概念
          • 2. 使用指数退避策略的原因
      • 2.2.3 可选步骤:使用心跳监测机制
  • 3. 代码
    • 3.1 客户端 TimeoutClient
    • 3.2 客户端的重连处理器 TimeoutHandler
    • 3.3 服务器
    • 3.4 测试方法
  • 4. 总结


1. 处理连接超时和断开重连的原因

在网络编程中,处理 连接超时断开重连 是非常必要的,主要有以下几点原因:

  • 应对网络不稳定的情景:网络中存在拥塞、信号干扰等问题,会导致连接超时或断开。若不处理,程序可能等待或中断,浪费资源、影响业务
  • 保证系统可用性:服务器负载过高或故障恢复时,可能无法及时响应连接请求或使连接断开。处理这些情况能 提高连接成功率,让系统尽快恢复运行
  • 提升用户体验:可避免用户长时间等待,保证业务连续性,避免因连接问题影响实时应用,增强用户对应用的好感。

2. 处理连接超时和断开重连的方法

2.1 处理连接超时

处理连接超时共有以下两步:

2.1.1 步骤一:配置连接超时时间

在客户端 Bootstrap 中配置连接超时参数,若超时则触发异常

// 5s 连接超时
option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)

2.1.2 步骤二:监听连接结果

给连接操作添加监听器,这个监听器负责 处理连接失败并触发重连

bootstrap.connect(/* host */, /* port */).addListener((ChannelFutureListener) f -> {if (!f.isSuccess()) {System.out.println("连接失败,尝试重连...");// 触发重连逻辑,之后的代码会展示}});

注:重连只是处理连接超时的一种手段,还可以通过提示用户“网络卡顿,无法连接到服务器”的方式来处理连接超时。

2.2 处理断开重连

处理断开重连也有关键的两步:

2.2.1 步骤一:监听连接断开事件

ChannelHandler 中监听 channelInactive 事件,触发重连

@Override
public void channelInactive(ChannelHandlerContext ctx) {System.out.println("连接断开,启动重连");// 触发重连逻辑,之后的代码会展示ctx.fireChannelInactive();
}

2.2.2 步骤二:实现重连逻辑

使用 指数退避策略 调度重连,避免频繁尝试。

/*** 执行重连操作*/
public static void reconnect() {// retries 表示当前重连次数,是一个私有成员字段,MAX_RETRIES 表示最大重连次数,是一个私有静态常量if (retries >= MAX_RETRIES) {System.out.println("重连次数已达上限,放弃连接");return;}// 下一次重试前需要等待的最大时间为 2 的 retries 次方 和 30 中的较小值int maxRetryDelay = Math.min(30, 1 << retries++);// 下一次重试前需要等待的时间为 [1, 最大等待时间) 区间中的一个随机值int retryDelay = maxRetryDelay == 1 ? 1 : ThreadLocalRandom.current().nextInt(1, maxRetryDelay);System.out.println("第" + retries + "次重试,等待" + retryDelay + "秒");Bootstrap bootstrap = TimeoutClient.getBootstrap();bootstrap.config().group().schedule(() -> {bootstrap.connect(TimeoutClient.HOST, TimeoutClient.PORT).addListener(TIMEOUT_RECONNECT_LISTENER);}, retryDelay, TimeUnit.SECONDS);
}
指数退避策略
1. 指数退避策略的概念

指数退避策略 (Exponential Backoff) 是一种在重试机制中常用的算法,用于 处理因资源竞争、网络故障等原因导致的操作失败。其核心思想是 在每次操作失败后,等待一段随机的时间再进行下一次尝试,并且这个等待时间会随着失败次数的增加而呈指数级增长
 
一般而言,指数退避策略的等待时间计算公式可以表示为: T = b a s e × 2 n × r a n d o m T = base \times 2^n \times random T=base×2n×random。其中:

  • T T T下一次重试前需要等待的时间
  • b a s e base base初始的基本等待时间
  • n n n当前重连的次数
  • r a n d o m random random一个介于 0 到 1 之间的随机数,引入随机数是为了 避免多个客户端在同一时刻重试,从而减少冲突的可能性
2. 使用指数退避策略的原因
  • 减少资源竞争:在生产环境中,多个客户端可能会同时尝试访问同一个资源。如果没有退避策略,这些客户端会在失败后立刻再次尝试,这会导致资源竞争加剧,使得更多的请求失败。而指数退避策略通过让客户端在失败后等待不同的时间再重试,分散了重试的时间点,降低了资源竞争的概率,提高了资源的利用率类似于 Redis 缓存雪崩 问题的 随机过期时间 解决方案。
  • 应对临时故障许多操作失败可能是由于临时的网络波动、服务器过载等原因引起的,这些问题通常会在短时间内自行解决。指数退避策略让客户端在每次失败后等待更长的时间再重试,给系统留出更多的时间来恢复正常,从而提高了重试成功的概率
  • 节省系统资源频繁的重试操作会消耗客户端和服务器的系统资源。使用指数退避策略可以 减少不必要的重试次数,降低系统资源的消耗,提高系统的性能和效率

2.2.3 可选步骤:使用心跳监测机制

客户端与服务器之间,可以使用心跳监测机制,从而判断它们之间建立的连接是否存活。如果存活,则无需任何操作;否则不存活,需要断开连接,并进行重连操作。使用心跳监测机制的方法可以参考 Netty——心跳监测机制。

3. 代码

3.1 客户端 TimeoutClient

/*** 有超时重连机制的客户端*/
public class TimeoutClient {public static final String HOST = "127.0.0.1";public static final int PORT = 8888;private static Bootstrap bootstrap;public static Bootstrap getBootstrap() {return bootstrap;}public static void main(String[] args) {final EventLoopGroup group = new NioEventLoopGroup();bootstrap = new Bootstrap().group(group).channel(NioSocketChannel.class)// 5s 连接超时.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new MsgDecoder()).addLast(new MsgEncoder()).addLast(new TimeoutHandler());}});Runtime.getRuntime().addShutdownHook(new Thread(group::shutdownGracefully));bootstrap.connect(HOST, PORT).addListener(TimeoutHandler.TIMEOUT_RECONNECT_LISTENER);}
}

3.2 客户端的重连处理器 TimeoutHandler

/*** 客户端的重连处理器*/
public class TimeoutHandler extends ChannelInboundHandlerAdapter {/*** 最大重连次数*/private static final int MAX_RETRIES = 5;/*** 当前重连次数*/private static int retries = 0;/*** 连接超时后进行重连的事件监听器*/public static final ChannelFutureListener TIMEOUT_RECONNECT_LISTENER = f -> {if (!f.isSuccess()) {System.out.println("连接失败,尝试重连...");reconnect();}};/*** 执行重连操作*/public static void reconnect() {if (retries >= MAX_RETRIES) {System.out.println("重连次数已达上限,放弃连接");return;}// 下一次重试前需要等待的最大时间为 2 的 retries 次方 和 30 中的较小值int maxRetryDelay = Math.min(30, 1 << retries++);// 下一次重试前需要等待的时间为 [1, 最大等待时间) 区间中的一个随机值int retryDelay = maxRetryDelay == 1 ? 1 : ThreadLocalRandom.current().nextInt(1, maxRetryDelay);System.out.println("第" + retries + "次重试,等待" + retryDelay + "秒");Bootstrap bootstrap = TimeoutClient.getBootstrap();bootstrap.config().group().schedule(() -> {bootstrap.connect(TimeoutClient.HOST, TimeoutClient.PORT).addListener(TIMEOUT_RECONNECT_LISTENER);}, retryDelay, TimeUnit.SECONDS);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {System.out.println("连接断开,启动重连");reconnect();ctx.fireChannelInactive();}
}

3.3 服务器

服务器代码可以参考 Netty——心跳监测机制 中实现的 HeartbeatServer

3.4 测试方法

  • 测试断开重连的处理:启动服务器和客户端。对于以上实现的客户端,在与该服务器建立连接后不会主动发送数据,如果超过 3s,该服务器会判定客户端宕机,断开连接,然后就会在客户端中触发 channelInactive 事件,从而触发断开重连机制。
  • 测试连接超时的处理:不要启动服务器,只启动客户端,就可以看到客户端重试连接最多 5 次。在这 5 次之内,如果启动服务器,则可以正常建立连接。

4. 总结

通过处理连接超时和断开重连,可以提高系统的健壮性,提升用户体验。在重连时,可以使用指数退避策略来减少资源的竞争、节省系统资源。

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

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

相关文章

Redis 与 AI:从缓存到智能搜索的融合之路

Redis 与 AI&#xff1a;从缓存到智能搜索的融合之路 在当今数字化时代&#xff0c;Redis 不仅是一个高性能的缓存系统&#xff0c;更是一个强大的 AI 支持平台。Redis 通过其向量数据库功能和 AI 工具&#xff0c;为现代应用提供了独特的技术优势。 一、Redis 的 AI 能力 &…

LeetCode435 -- 预定会议问题

0. ref 参考自 1. 题目描述 预定会议问题&#xff1a;给定我们一堆区间&#xff0c;区间不能重叠&#xff08; [ 1 , 2 ] [1,2] [1,2] 和 [ 2 , 3 ] [2,3] [2,3] 的 2 2 2 不算重叠&#xff09;&#xff0c;求最多能保留多少个区间&#xff1f; 做法&#xff1a;贪心&#…

leetcode51-N皇后

leetcode 51 思路 本题可以使用回溯算法来解决。回溯算法通过尝试所有可能的解决方案来找到问题的解的算法&#xff0c;当发现当前的选择无法得到有效的解决方案时&#xff0c;就回溯到上一步&#xff0c;尝试其他的选择。对于 N 皇后问题&#xff0c;我们可以逐行放置皇后&…

linux paste 命令

paste 是 Linux 中一个用于水平合并文件内容的命令行工具&#xff0c;它将多个文件的对应行以并行方式拼接&#xff0c;默认用制表符&#xff08;Tab&#xff09;分隔。 1. 基本语法 paste [选项] 文件1 文件2 ... 2. 常用选项 选项说明-d指定拼接后的分隔符&#xff08;默…

Linux 入门:基础开发工具(上)vim,gcc/g++,make/makefile

目录 一.软件包管理器 一&#xff09;.软件包 二&#xff09;.安装软件 三&#xff09;.删除软件 二.编辑器vim 一&#xff09;.vim的基本介绍 1.正常/普通/命令模式(Normal mode) 2.插入模式(Insert mode) 3.底行模式(last line mode) 二&#xff09;.vim的基本操作 …

在CPU服务器上部署Ollama和Dify的过程记录

在本指南中&#xff0c;我将详细介绍如何在CPU服务器上安装和配置Ollama模型服务和Dify平台&#xff0c;以及如何利用Docker实现这些服务的高效部署和迁移。本文分为三大部分&#xff1a;Ollama部署、Dify环境配置和Docker环境管理&#xff0c;适合需要在本地或私有环境中运行A…

请求被中止: 未能创建 SSL/TLS 安全通道。

需要安装vs2019社区办&#xff0c;下载VisualStudioSetup.exe后&#xff0c;报无法从"https://aka,ms/vs/16/release/channel"下载通道清单错误&#xff0c;接着打开%temp%目录下的最新日志&#xff0c;发现日志里报&#xff1a; [27d4:000f][2025-04-04T21:15:43] …

第六课:AI绘画进阶模型

文章目录 Part.01 文本嵌入(Embeddings)Part.02 低秩模型(LoRa)Part.03 超网络(Hypernetwork)Part.01 文本嵌入(Embeddings) Embeddings(Textual Inversion)Checkpoint如果是字典,Embeddings就是书签,让检索更加高效深度学习中Embeddings叫做嵌入式向量使用方法:下载Embeddi…

阅读分析Linux0.11 /boot/setup.s

目录 第一部分第二部分第三部分 该源文件功能分为三部分&#xff1a; &#xff08;1&#xff09;源文件开始部分是通过各种中断指令&#xff0c; 初始化计算机的组成硬件&#xff0c;获得硬件的参数&#xff0c;然后保存到段空间0X9000。该空间原来是保存加载到内存的引导扇区内…

TSMaster在新能源汽车研发测试中的硬核应用指南

——从仿真到标定&#xff0c;全面赋能智能汽车开发 引言&#xff1a;新能源汽车测试的挑战与TSMaster的破局之道 新能源汽车的快速发展对研发测试提出了更高要求&#xff1a;复杂的电控系统、高实时性通信需求、多域融合的验证场景&#xff0c;以及快速迭代的开发周期。传统测…

web漏洞靶场学习分享

靶场&#xff1a;pikachu靶场 pikachu漏洞靶场漏洞类型: Burt Force(暴力破解漏洞)XSS(跨站脚本漏洞)CSRF(跨站请求伪造)SQL-Inject(SQL注入漏洞)RCE(远程命令/代码执行)Files Inclusion(文件包含漏洞)Unsafe file downloads(不安全的文件下载)Unsafe file uploads(不安全的文…

《Linux内存管理:实验驱动的深度探索》【附录】【实验环境搭建 4】【Qemu 如何模拟numa架构】

我们在学习 linux 内核时&#xff0c;会涉及到很多 numa 的知识&#xff0c;那我们该如何在 qemu 中模拟这种情况&#xff0c;来配合我们的学习呢&#xff1f; 我们该如何模拟 如下的 numa 架构 Qemu 模拟 NUMA 架构 -M virt,gic-version3,virtualizationon,typevirt \ -cp…

YOLOv12 从预训练迈向自主训练,第一步数据准备

视频讲解&#xff1a; YOLOv12 从预训练迈向自主训练&#xff0c;第一步数据准备 前面复现过yolov12&#xff0c;使用pre-trained的模型进行过测试&#xff0c;今天来讲下如何训练自己的模型&#xff0c;第一步先准备数据和训练格式 https://gitcode.com/open-source-toolkit/…

Keil 5 找不到编译器 Missing:Compiler Version 5 的解决方法

用到自记&#xff1a; 下载地址&#xff1a; Keil5 MDK541.zip ​编辑https://pan.baidu.com/s/1bOPsuVZhD_Wj4RJS90Mbtg?pwdMDK5 问题描述 没有找到 compiler version5 &#xff1a; 1. 下载 Arm Compiler 5 也可以直接点击下载文章开头的文件。 2. 安装 直接安装在KEI…

结肠镜3D视频数据集-C3VD论文中文版

文章目录 标题作者摘要一、介绍1.1. 相关工作1.1.1. 内镜重建数据集1.1.2. 注册真实和虚拟内窥镜图像1.1.3. 2D-3D注册1.2. 贡献 二、方法2.1. 幻影模型生产2.2. 数据采集2.3. 注册流程概述2.3.1. 数据预处理2.3.2. 目标深度估计2.3.3. 渲染深度帧2.3.4. 边缘损失和优化 2.4. 模…

hadoop 集群的常用命令

# 查看HDFS目录内容 hadoop fs -ls /path # 创建目录 hadoop fs -mkdir /path/to/dir # 上传本地文件到HDFS hadoop fs -put localfile /hdfs/path # 下载HDFS文件到本地 hadoop fs -get /hdfs/path localfile # 查看文件内容 hadoop fs -cat /hdfs/path/file # 删除文件/…

MaxEnt物种分布建模全流程;R+ArcGIS+MaxEnt模型物种分布模拟、参数优化方法、结果分析制图与论文写作

融合R语言的MaxEnt模型具有以下具体优势&#xff1a; 数据处理高效便捷 &#x1f4ca;强大的数据预处理功能&#xff1a;R语言提供了丰富的数据处理工具&#xff0c;能够轻松完成数据清洗、筛选、转换等操作&#xff0c;为MaxEnt模型提供高质量的输入数据。 &#x1f310;自动…

Java基础 4.4

1.方法快速入门 public class Method01 {//编写一个main方法public static void main(String[] args) {//方法使用//1.方法写好后&#xff0c;如果不去调用(使用)&#xff0c;不会输出Person p1 new Person();p1.speak();//调用方法 p1.cal01();//调用计算方法1p1.cal02(10);…

Tiktok矩阵运营中使用云手机的好处

Tiktok矩阵运营中使用云手机的好处 云手机在TikTok矩阵运营中能够大幅提高管理效率、降低封号风险&#xff0c;并节省成本&#xff0c;是非常实用的运营工具。TikTok矩阵运营使用云手机有很多优势&#xff0c;特别是对于需要批量管理账号、提高运营效率的团队来说。以下是几个…

指针函数、函数指针和指针函数指针的全面总结

C中指针函数、函数指针和指针函数指针的全面总结 一、核心概念区别 概念本质声明示例核心特征指针函数返回指针的函数int* func(int);函数定义&#xff0c;返回值是指针类型函数指针指向函数的指针int (*ptr)(int);变量&#xff0c;存储函数地址指针函数指针指向指针函数的指…