解決使用lettuce連接Redis超時的問題(tcpUserTimeout 參數失效問題)

問題背景

lettuce 連接Redis的主從實例,當主節的主機異常下電重啟后,由于沒有發送RST 包,導致 lettuce 一直在復用之前的TCP鏈接,然后會出現連接超時的情況。一直出現io.lettuce.core.RedisCommandTimeoutException: Command timed out after 的錯誤,直到約15分鐘后,TCP不再重傳,斷開連接才恢復
詳細原因參考:
https://juejin.cn/post/7494573414150438927#heading-5
https://www.modb.pro/db/1711557186789908480
https://github.com/lettuce-io/lettuce-core/issues/2082
https://support.huaweicloud.com/usermanual-dcs/dcs-ug-211105002.html

解決方案

最簡單的是修改客戶端操作系統的TCP重傳次數,例如改為 8次。就可以不再等待15分鐘
sysctl -w net.ipv4.tcp_retries2=8
但是由于影響較大,也會影響主機上其他的TCP連接,此方案被排除。
于是按照官方提供的方案(參考:https://github.com/lettuce-io/lettuce-core/issues/2082https://support.huaweicloud.com/usermanual-dcs/dcs-ug-211105002.html),升級 lettuce 的依賴到 6.3.0,同時設置tcpUserTimeout 參數
升級版本并設置tcpUserTimeout,應用日志顯示參數不生效,同時驗證后確實無效,問題依然存在
采用如下依賴:

<dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.3.0.RELEASE</version>
</dependency><dependency><groupId>io.netty</groupId><artifactId>netty-transport-native-epoll</artifactId><version>4.1.100.Final</version><classifier>linux-x86_64</classifier>
</dependency>

日志顯示:

2025-05-06 13:40:05.024  WARN 1939829 --- [nio-8888-exec-1] io.lettuce.core.ConnectionBuilder        : Cannot apply TCP User Timeout options to channel type io.netty.channel.socket.nio.NioSocketChannel
2025-05-06 13:40:05.390  WARN 1939829 --- [ioEventLoop-6-1] io.lettuce.core.ConnectionBuilder        : Cannot apply TCP User Timeout options to channel type io.netty.channel.socket.nio.NioSocketChannel
2025-05-06 13:40:05.394  WARN 1939829 --- [ioEventLoop-6-1] io.lettuce.core.ConnectionBuilder        : Cannot apply TCP User Timeout options to channel type io.netty.channel.socket.nio.NioSocketChannel
2025-05-06 13:40:05.396  WARN 1939829 --- [ioEventLoop-6-1] io.lettuce.core.ConnectionBuilder        : Cannot apply TCP User Timeout options to channel type io.netty.channel.socket.nio.NioSocketChannel

分析依賴判斷是netty的沖突問題于是修改依賴的配置如下:

		<dependency><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId><version>6.3.0.RELEASE</version></dependency><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.100.Final</version></dependency>

應用啟動不再提示,并且在故障后30s出現重連的日志,說明tcpUserTimeout參數生效了。

2025-05-07 09:07:59.411  INFO 2112812 --- [xecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was 10.50.190.43:6379
2025-05-07 09:07:59.419  INFO 2112812 --- [llEventLoop-6-3] i.l.core.protocol.ReconnectionHandler    : Reconnected to 10.50.190.43:6379

Redis配置類如下:

@Configuration
public class RedisConfig {@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port:6379}")private Integer redisPort = 6379;@Value("${spring.redis.database:0}")private Integer redisDatabase = 0;@Value("${spring.redis.password:}")private String redisPassword;@Value("${spring.redis.connect.timeout:2000}")private Integer redisConnectTimeout = 2000;@Value("${spring.redis.read.timeout:2000}")private Integer redisReadTimeout = 2000;/*** TCP_KEEPALIVE 配置參數:* 兩次 keepalive 間的時間間隔 = TCP_KEEPALIVE_TIME = 30* 連接空閑多久開始 keepalive = TCP_KEEPALIVE_TIME/3 = 10* keepalive 幾次之后斷開連接 = TCP_KEEPALIVE_COUNT = 3*/private static final int TCP_KEEPALIVE_TIME = 30;/*** TCP_USER_TIMEOUT 連接空閑限制時間,解決Lettuce長時間超時問題。* refer: https://github.com/lettuce-io/lettuce-core/issues/2082*/private static final int TCP_USER_TIMEOUT = 30;@Beanpublic LettuceConnectionFactory redisConnectionFactory(LettuceClientConfiguration clientConfiguration) {RedisStandaloneConfiguration standaloneConfiguration = new RedisStandaloneConfiguration();standaloneConfiguration.setHostName(redisHost);standaloneConfiguration.setPort(redisPort);standaloneConfiguration.setDatabase(redisDatabase);standaloneConfiguration.setPassword(redisPassword);LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(standaloneConfiguration, clientConfiguration);connectionFactory.setDatabase(redisDatabase);return connectionFactory;}@Beanpublic LettuceClientConfiguration clientConfiguration() {SocketOptions socketOptions = SocketOptions.builder().keepAlive(SocketOptions.KeepAliveOptions.builder()// 兩次 keepalive 間的時間間隔.idle(Duration.ofSeconds(TCP_KEEPALIVE_TIME))// 連接空閑多久開始 keepalive.interval(Duration.ofSeconds(TCP_KEEPALIVE_TIME / 3))// keepalive 幾次之后斷開連接.count(3)// 是否開啟保活連接.enable().build()).tcpUserTimeout(SocketOptions.TcpUserTimeoutOptions.builder()// 解決服務端rst導致的長時間超時問題.tcpUserTimeout(Duration.ofSeconds(TCP_USER_TIMEOUT)).enable().build())// tcp 連接超時設置.connectTimeout(Duration.ofMillis(redisConnectTimeout)).build();ClientOptions clientOptions = ClientOptions.builder().autoReconnect(true).pingBeforeActivateConnection(true).cancelCommandsOnReconnectFailure(false).disconnectedBehavior(ClientOptions.DisconnectedBehavior.ACCEPT_COMMANDS).socketOptions(socketOptions).build();LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder().commandTimeout(Duration.ofMillis(redisReadTimeout)).readFrom(ReadFrom.MASTER).clientOptions(clientOptions).build();return clientConfiguration;}@BeanRedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);System.out.println("SocketOptions: " + redisConnectionFactory.getClientConfiguration().getClientOptions().get().getSocketOptions().getTcpUserTimeout().getTcpUserTimeout().toString());return template;}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/78932.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/78932.shtml
英文地址,請注明出處:http://en.pswp.cn/web/78932.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何使用python保存字典

在Python中&#xff0c;可以通過多種方式將字典&#xff08;dict&#xff09;保存到文件中&#xff0c;并能夠隨時讀取恢復。以下是幾種常見的方法&#xff1a; 1. 使用 json 模塊&#xff08;推薦&#xff09; 適用場景&#xff1a;需要人類可讀的文件格式&#xff0c;且數據不…

SQL 與 Python:日期維度表創建的不同選擇

文章目錄 一、日期維度表概述日期維度表結構 二、使用 SQL 創建日期維度表2.1 表結構設計2.2 數據插入2.3 SQL 創建方式的優勢與局限 三、使用 Python 創建日期維度表3.1 依賴庫引入3.2 代碼實現3.3 Python 創建方式的優勢與局限 四、應用場景與選擇建議4.1 應用場景4.2 選擇建…

如何用postman進行批量操作

業務場景&#xff1a; 有些時候&#xff0c;我們會需要批量的將SAP B1系統中的幾千條的數據刪除或者取消單據&#xff0c;這個時候&#xff0c;一條條去操作&#xff0c;指定是到猴年馬月了。SAP Business One本身提供了DTW這個工具&#xff0c;但是這個更新&#xff0c;可以操…

Mysql如何完成數據的增刪改查(詳解從0到1)

前言&#xff1a; Mysql可能是每個程序員的必修課&#xff0c;可以說是使用起來是沒有什么問題的&#xff0c;但是作為一名合格的程序猿&#xff0c;深入學習Mysql的內部工作原理是非常有必要的&#xff0c;主要是理解和學習Mysql的底層思想&#xff0c;希望在日后如遇到一些&…

單片機嵌入式按鍵庫

kw_btn庫說明 本庫主要滿足嵌入式按鍵需求&#xff0c;集成了常用的按鍵響應事件&#xff1a;高電平、低電平、上升沿、下降沿、單擊、雙擊、長按鍵事件。可以裸機運行&#xff0c;也可以配合實時操作系統運行。 本庫開源連接地址&#xff1a;連接 實現思路 本庫采用C語言進行…

Qt—鼠標移動事件的趣味小程序:會移動的按鈕

1.項目目標 本次根據Qt的鼠標移動事件實現一個趣味小程序&#xff1a;當鼠標移動到按鈕時&#xff0c;按鈕就會隨機出現在置&#xff0c;以至于根本點擊不到按鈕。????? 2.項目步驟 首先現在ui界面設計控件(也可以用代碼的方式創建&#xff0c;就不多說了) 第一個按鈕不需…

MySQL的information_schema在SQL注入中的關鍵作用與防御策略

目錄 一、information_schema的核心價值 二、攻擊利用場景與示例 1. 聯合查詢注入&#xff08;Union-Based&#xff09; 2. 報錯注入&#xff08;Error-Based&#xff09; 3. 布爾盲注&#xff08;Boolean Blind&#xff09; 4. 時間盲注&#xff08;Time-Based&#xff0…

c語言 關鍵字--目錄

下面是詳細介紹的鏈接 1.c語言 關鍵字 2.typedef 關鍵字 3.volatile 關鍵字 4.register 關鍵字 5.const關鍵字用法 6.extern關鍵字 7.sizeof關鍵字

python爬蟲爬取網站圖片出現403解決方法【僅供學習使用】

基于CSDN第一篇文章&#xff0c;Python爬蟲之入門保姆級教程&#xff0c;學不會我去你家刷廁所。 這篇文章是2021年作者發表的&#xff0c;由于此教程&#xff0c;網站添加了反爬機制&#xff0c;有作者通過添加cookie信息來達到原來的效果&#xff0c;Python爬蟲添加Cookies以…

docker創建一個centOS容器安裝軟件(以寶塔為例)的詳細步驟

備忘&#xff1a;后續偶爾忘記了docker虛擬機與宿主機的端口映射關系&#xff0c;來這里查看即可&#xff1a; docker run -d \ --name baota \ --privilegedtrue \ -p 8888:8888 \ -p 8880:80 \ -p 8443:443 \ -p 8820:20 \ -p 8821:21 \ -v /home/www:/www/wwwroot \ centos…

linux 使用nginx部署ssl證書,將http升級為https

前言 本文基于&#xff1a;操作系統 CentOS Stream 8 使用工具&#xff1a;Xshell 8、Xftp 8 服務器基礎環境&#xff1a; nginx - 請查看 linux 使用nginx部署vue、react項目 所需服務器基礎環境&#xff0c;請根據提示進行下載、安裝。 1.下載證書 以騰訊云為例&#x…

日常開發中,iOS 性能調優我們怎么做?

日常開發中&#xff0c;iOS 性能調優我們怎么做&#xff1f;聊聊我用過的幾款工具 最近在給一個 iOS 視頻類 App 做性能優化&#xff0c;過程中踩了不少坑&#xff0c;也用了一些不錯的工具&#xff0c;今天就以一個開發者視角隨便聊聊我在調試過程中的一些經驗。 一、性能問…

Redis ⑨-Jedis | Spring Redis

Jedis 通過 Jedis 可以連接 Redis 服務器。 通過 Maven 引入 Jedis 依賴。 <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><versi…

【人工智能】解鎖AI潛能:LM Studio多模型并行運行DeepSeek與開源大模型的實踐指南

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著大語言模型(LLM)的快速發展,LM Studio作為一款本地化部署工具,以其簡單易用的圖形化界面和強大的模型管理能力受到廣泛關注。本文深…

Node.js面試題

一、什么是Node.js&#xff1f; Node.js 是一個開源的跨平臺 JavaScript 運行時環境&#xff0c;允許開發者在服務器端運行 JavaScript 代碼。它基于 Chrome 的 V8 JavaScript 引擎構建&#xff0c;能夠高效地處理 I/O 操作&#xff0c;適合構建高性能的網絡應用。 異步非阻塞&…

Playwright MCP 入門實戰:自動化測試與 Copilot 集成指南

什么是 MCP&#xff1f; MCP&#xff08;Model Context Protocol&#xff09; 是一種為大語言模型&#xff08;LLM&#xff09;設計的協議&#xff0c;MCP充當 LLM 與實際應用之間的橋梁或“翻譯器”&#xff0c;將自然語言轉化為結構化指令&#xff0c;使得模型可以更精確、高…

達夢DM數據庫安裝步驟

文章目錄 1、下載并解壓縮2、安裝DM數據庫2.1 運行安裝程序2.2 選擇語言與時區2.3 安裝向導2.4 許可證協議2.5 Key文件2.6 選擇組件2.7 安裝位置2.8 安裝前小結2.9 安裝過程2.10 已完成2.11 初始化 3、配置實例3.1選擇操作方式3.2創建數據庫模版3.3指定數據庫目錄3.4數據庫標識…

電商雙11美妝數據分析(2)

接下來用seaborn包給出每個店鋪各個大類以及各個小類的銷量銷售額 關于性別 接下來考慮性別因素&#xff0c;了解各類產品在男性消費者中的銷量占比 男士的銷量基本來自于清潔類&#xff0c;其次是補水類。而這兩類正是總銷量中占比最高的兩類。 非男士專用中&#xff0c;補水…

54.實現Trie(前綴樹)

Trie(發音類似 "try")或者說 前綴樹 是一種樹形數據結構&#xff0c;用于高效地存儲和檢索字符串數據集中的鍵。這一數據結構有相當多的應用情景&#xff0c;例如自動補全和拼寫檢查。 請你實現 Trie 類&#xff1a; Trie() 初始化前綴樹對象。void insert(String wo…

Excel文件批量處理指南 | 用VBA一鍵操作文件夾所有工作簿

系列文章 Excel跨文件夾批處理黑科技 | 用VBA遞歸遍歷所有子目錄 目錄 系列文章&#x1f4c1; Excel文件批量處理指南 | 用VBA一鍵操作文件夾所有工作簿一、場景痛點與解決方案二、核心代碼架構解析1. 文件遍歷引擎2. 安全打開機制3. 錯誤處理框架 三、7大實戰應用場景場景1&a…