【Azure Redis】Lettuce客戶端遇見連線Azure Redis長達15分鐘的超時

路边两盏灯發表於2024-03-14

問題描述

在AKS環境中,應用使用Lettuce客戶端連線Azure Redis,遇見了長達15分鐘的超時情況

問題解答

在AKS中的節點作業系統,通常情況都是使用Linux,所以在連線Redis服務時候,TCP的連線需要基於系統級(Linux)的配置。 因為Azure Redis服務端對已經建立的連線最長空閒時間為10分鐘,如果超時,Azure Redis會主動發起RST來斷開TCP連線,而非正常的斷開操作(四次揮手: FIN/ACK指令)。因此,因為伺服器停止響應而未正常關閉連線時,Linux客戶端 TCP 將繼續重新傳輸資料包 15 分鐘,然後才認為這個TCP連線死掉,直到這時,系統才會讓Reids客戶端重新建立新的連線。

【Azure Redis】Lettuce客戶端遇見連線Azure Redis長達15分鐘的超時

Lettuce客戶端 6.1.0 版本之前,並沒有在底層適配TCP Keepalive 功能或是keepalive的發包間隔時間超過了10分鐘,並且在Command Timeout 狀態下無法直接放棄一個連線並馬上重連,而是選擇進入TCP重傳狀態等待連線恢復。

現在,Lettuce 已經在6.3.0版本中修復這個問題。透過配置TCP_USER_TIMEOUT來減少TCP重傳的時間。

注:由於Azure Redis的升級機制或是其他意外問題(Failover),導致連線異常斷開是預期的。所以必須要從Lettuce客戶端入手,加強Lettuce的保活以及斷開重連機制,從而將連線異常斷開的影響降到最低。

附錄一:關於Lettuce的Issue細節

請見:https://github.com/lettuce-io/lettuce-core/issues/2082#issuecomment-1702782618

@mp911de I verified 6.3.0.BUILD-SNAPSHOT and it succeeded. The details are as follows. I am not sure if we need to update a document to provide examples and reference it during official release. If necessary, please let me know where to add or modify it.

1. DO NOT configure TCP_USER_TIMEOUT will continue to be retransmitted.

【Azure Redis】Lettuce客戶端遇見連線Azure Redis長達15分鐘的超時

2. Configure TCP_ USER_ TIMEOUT is 30 seconds, and a reconnection will be initiated using a new port 30 seconds after the first retransmission occurs!

【Azure Redis】Lettuce客戶端遇見連線Azure Redis長達15分鐘的超時

my pom.xml is (notice: Linux need use native-epoll)

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

in debug, will see this log:

2023-09-01 21:30:20 [main] DEBUG i.l.core.resource.EpollProvider - Starting with epoll library
2023-09-01 21:30:20 [main] DEBUG i.l.c.r.DefaultEventLoopGroupProvider - Allocating executor io.netty.channel.e

參考資料

Linux 託管客戶端應用程式的 TCP 設定: https://docs.azure.cn/zh-cn/azure-cache-for-redis/cache-best-practices-connection#tcp-settings-for-linux-hosted-client-applications
Lettuce TCP_USER_TIMEOUT : https://github.com/lettuce-io/lettuce-core/issues/2082#issuecomment-1702782618

相關文章