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.pswp.cn/news/900156.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/900156.shtml
英文地址,請注明出處:http://en.pswp.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;存儲函數地址指針函數指針指向指針函數的指…