天天看點

一文詳解長連接配接黑洞重制和分析

作者:閃念基因
一文詳解長連接配接黑洞重制和分析

導讀

本文先通過重制在不同業務線反複出現的問題,較長的描述了從業務、資料庫、OS等不同的角度來分析如何解決它。

這是一個存在多年,遍及各個不同的業務又反反複複地在集團内部出現的一個問題,本文先通過重制展示這個問題,然後從業務、資料庫、OS等不同的角度來分析如何解決它,這個問題值得每一位研發同學重視起來,避免再次踩到。

背景

為了高效率應對故障,本文嘗試回答如下一些問題:

  • 為什麼資料庫crash重新開機恢複後,業務還長時間不能恢複?
  • 我依賴的業務做了高可用切換,但是我的業務長時間報錯。
  • 我依賴的服務下掉了一個節點,為什麼我的業務長時間報錯?
  • 客戶做變配,更新雲服務節點規格,為什麼會導緻客戶業務長時間報錯?

目的:希望通過這篇文章盡可能地減少故障時長、讓業務快速從故障中恢複。

重制

空說無憑,先也通過一次真實的重制來展示這個問題。

LVS+MySQL高可用切換

OS預設配置參數:

#sysctl -a |grep -E "tcp_retries|keepalive"

net.ipv4.tcp_keepalive_intvl = 30

net.ipv4.tcp_keepalive_probes = 5

net.ipv4.tcp_keepalive_time = 10

net.ipv4.tcp_retries1 = 3

net.ipv4.tcp_retries2 = 15  //主要是這個參數,預設以及alios 幾乎都是15           

LVS對外服務端口是3001,後面挂的是3307,假設3307是目前的Master,Slave是3306,當檢測到3307異常後會從LVS上摘掉3307挂上3306做高可用切換。

一文詳解長連接配接黑洞重制和分析

切換前的LVS狀态:

#ipvsadm -L --timeout

Timeout (tcp tcpfin udp): 900 120 300

#ipvsadm -L -n

IP Virtual Server version 1.2.1 (size=4096)

Prot LocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  127.0.0.1:3001 rr

  -> 127.0.0.1:3307               Masq    1      0          0           

Sysbench啟動壓力模拟使用者通路,在31秒的時候模拟管控檢測到3307的Master無法通路,是以管控執行切主把3306的Slave提升為新的Master,同時到LVS摘掉 3307,挂上3306,此時管控端着冰可樂、翹着二郎腿,得意地說,你就看吧我們管控牛不牛、我們的高可用牛不牛,這一套行雲流水3秒鐘不到全搞定。

切換指令如下:

#cat del3307.sh
ipvsadm -d -t  127.0.0.1:3001 -r 127.0.0.1:3307 ; ipvsadm -a -t  127.0.0.1:3001 -r 127.0.0.1:3306 -m           

此時Sysbench運作狀态,在第32秒如期跌0:

#/usr/local/bin/sysbench --debug=on --mysql-user='root' --mysql-password='123' --mysql-db='test' --mysql-host='127.0.0.1' --mysql-port='3001' --tables='16'  --table-size='10000' --range-size='5' --db-ps-mode='disable' --skip-trx='on' --mysql-ignore-errors='all' --time='11080' --report-interval='1' --histogram='on' --threads=1 oltp_read_write run
sysbench 1.1.0 (using bundled LuaJIT 2.1.0-beta3)


Running the test with following options:
Number of threads: 1
Report intermediate results every 1 second(s)
Debug mode enabled.


Initializing random number generator from current time




Initializing worker threads...


DEBUG: Worker thread (#0) started
DEBUG: Reporting thread started
DEBUG: Worker thread (#0) initialized
Threads started!


[ 1s ] thds: 1 tps: 51.89 qps: 947.00 (r/w/o: 739.44/207.56/0.00) lat (ms,95%): 35.59 err/s 0.00 reconn/s: 0.00
[ 2s ] thds: 1 tps: 60.03 qps: 1084.54 (r/w/o: 841.42/243.12/0.00) lat (ms,95%): 22.28 err/s 0.00 reconn/s: 0.00
…………
[ 29s ] thds: 1 tps: 68.00 qps: 1223.01 (r/w/o: 952.00/271.00/0.00) lat (ms,95%): 16.12 err/s 0.00 reconn/s: 0.00
[ 30s ] thds: 1 tps: 66.00 qps: 1188.00 (r/w/o: 924.00/264.00/0.00) lat (ms,95%): 16.71 err/s 0.00 reconn/s: 0.00
[ 31s ] thds: 1 tps: 67.00 qps: 1203.96 (r/w/o: 937.97/265.99/0.00) lat (ms,95%): 17.95 err/s 0.00 reconn/s: 0.00
[ 32s ] thds: 1 tps: 22.99 qps: 416.85 (r/w/o: 321.88/94.96/0.00) lat (ms,95%): 15.55 err/s 0.00 reconn/s: 0.00
[ 33s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 34s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 35s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00           

5分鐘後故障報告大批量湧進來,客戶:怎麼回事,我們的業務挂掉10分鐘了,報錯都是通路MySQL逾時,趕緊給我看看,從監控确實看到10分鐘後客戶業務還沒恢複:

[ 601s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 602s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 603s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 604s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00           

這時oncall都被從被窩裡拎了起來,不知誰說了一句趕緊恢複吧,先試試把應用重新開機,5秒鐘後應用重新開機完畢,業務恢複,大家開心地笑了,又成功防禦住一次故障更新,還是重新開機大法好!

在業務/Sysbench QPS跌0期間可以看到3307被摘掉,3306成功挂上去了,但是沒有新連接配接建向3306,業務/Sysbench使勁薅着3307。

#ipvsadm -L -n --stats -t 127.0.0.1:3001

Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes

  -> RemoteAddress:Port

TCP  127.0.0.1:3001                      2   660294   661999 78202968  184940K

  -> 127.0.0.1:3306                      0        0        0        0        0

  

#ipvsadm -Lcn | head -10

IPVS connection entries

pro expire state       source             virtual            destination

TCP 13:11  ESTABLISHED 127.0.0.1:33864    127.0.0.1:3001     127.0.0.1:3307




#netstat -anto |grep -E "Recv|33864|3001|33077"

Proto Recv-Q Send-Q Local Address           Foreign Address         State       Timer

tcp        0    248 127.0.0.1:33864         127.0.0.1:3001          ESTABLISHED probe (33.48/0/8)

tcp6       0     11 127.0.0.1:3307          127.0.0.1:33864         ESTABLISHED on (49.03/13/0)           

直到900多秒後OS重試了15次發現都失敗,于是向業務/Sysbench傳回連接配接異常,觸發業務/Sysbench釋放異常連接配接重建新連接配接,新連接配接指向了新的Master 3306,業務恢複正常。

[ 957s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00

DEBUG: Ignoring error 2013 Lost connection to MySQL server during query,

DEBUG: Reconnecting 

DEBUG: Reconnected

[ 958s ] thds: 1 tps: 53.00 qps: 950.97 (r/w/o: 741.98/208.99/0.00) lat (ms,95%): 30.26 err/s 0.00 reconn/s: 1.00

[ 959s ] thds: 1 tps: 64.00 qps: 1154.03 (r/w/o: 896.02/258.01/0.00) lat (ms,95%): 22.69 err/s 0.00 reconn/s: 0.00

[ 960s ] thds: 1 tps: 66.00 qps: 1184.93 (r/w/o: 923.94/260.98/0.00) lat (ms,95%): 25.28 err/s 0.00 reconn/s: 0.00           

到這裡重制了故障中經常碰到的業務需要900多秒才能慢慢恢複,這個問題也就是TCP長連接配接流量黑洞。

如果我們把net.ipv4.tcp_retries2改5再來做這個實驗,就會發現業務/Sysbench 隻需要20秒就能恢複了,也就是這個流量黑洞從900多秒變成了20秒,這回oncall 不用再被從被窩裡拎出來了吧:

[ 62s ] thds: 1 tps: 66.00 qps: 1191.00 (r/w/o: 924.00/267.00/0.00) lat (ms,95%): 17.63 err/s 0.00 reconn/s: 0.00
[ 63s ] thds: 1 tps: 63.00 qps: 1123.01 (r/w/o: 874.00/249.00/0.00) lat (ms,95%): 17.63 err/s 0.00 reconn/s: 0.00
[ 64s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 65s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 66s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 67s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 68s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 69s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 70s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 71s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 72s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 73s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 74s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 75s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 76s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 77s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 78s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 79s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 80s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 81s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
[ 82s ] thds: 1 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s 0.00 reconn/s: 0.00
DEBUG: Ignoring error 2013 Lost connection to MySQL server during query,
DEBUG: Reconnecting 
DEBUG: Reconnected
[ 83s ] thds: 1 tps: 26.00 qps: 457.01 (r/w/o: 357.01/100.00/0.00) lat (ms,95%): 16.41 err/s 0.00 reconn/s: 1.00
[ 84s ] thds: 1 tps: 60.00 qps: 1086.94 (r/w/o: 846.96/239.99/0.00) lat (ms,95%): 26.68 err/s 0.00 reconn/s: 0.00
[ 85s ] thds: 1 tps: 63.00 qps: 1134.02 (r/w/o: 882.01/252.00/0.00) lat (ms,95%): 23.10 err/s 0.00 reconn/s: 0.00           

LVS+Nginx上重制

NGINX上重制這個問題:https://asciinema.org/a/649890

3分鐘的錄屏,這個視訊構造了一個LVS的HA切換過程,LVS後有兩個Nginx,模拟一個Nginx(Master)斷網後,将第二個Nginx(Slave)加入到LVS并将第一個Nginx(Master)從LVS摘除,期望業務能立即恢複,但實際上可以看到之前的所有長連接配接都沒有辦法恢複,進入一個流量黑洞。

TCP長連接配接流量黑洞原理總結

TCP長連接配接在發送包的時候,如果沒收到ack預設會進行15次重傳(net.ipv4.tcp_retries2=15,這個不要較真,會根據RTO時間大緻是15次),累加起來大概是924秒,是以我們經常看到業務需要15分鐘左右才恢複。這個問題存在所有TCP長連接配接中(幾乎沒有業務還在用短連接配接吧?),問題的本質和LVS/k8s Service都沒關系。

我這裡重制帶上LVS隻是為了場景示範友善。

這個問題的本質就是如果Server突然消失(當機、斷網,來不及發RST)用戶端如果正在發東西給Server就會遵循TCP重傳邏輯不斷地TCP retran,如果一直收不到Server的ack,大約重傳15次,900秒左右。是以不是因為有LVS導緻了這個問題,而是在某些場景下LVS有能力處理得更優雅,比如删除RealServer的時候LVS完全可以感覺這個動作并reset掉其上所有長連接配接。

為什麼在K8S上這個問題更明顯呢,K8S講究的就是服務不可靠,随時幹掉POD(切斷網絡),如果幹POD之前能kill-9(觸發reset)、或者close業務觸發斷開連接配接那還好,但是大多時候啥都沒幹,有強摘POD、有直接隔離等等,這些操作都會導緻對端隻能TCP retran。

怎麼解決

業務方

業務方要對自己的請求逾時時間有控制和兜底,不能任由一個請求長時間Hang在那裡。

比如JDBC URL支援設定SocketTimeout、ConnectTimeout,我相信其他産品也有類似的參數,業務方要設定這些值,不設定就是如上重制裡示範的900多秒後才恢複。

SocketTimeout

隻要是連接配接有機會設定SocketTimeout就一定要設定,具體值可以根據你們能接受的慢查詢來設定;分析、AP類的請求可以設定大一點。

最重要的:任何業務隻要你用到了TCP長連接配接一定要配置一個恰當的SocketTimeout,比如Jedis是連接配接池模式,底層逾時之後,會銷毀目前連接配接,下一次重建立連,就會連接配接到新的切換節點上去并恢複。

RFC 5482TCP_USER_TIMEOUT

RFC 5482[1]中增加了TCP_USER_TIMEOUT這個配置,通常用于定制當TCP網絡連接配接中出現資料傳輸問題時,可以等待多長時間前釋放網絡資源,對應Linux這個commit[2]。

TCP_USER_TIMEOUT是一個整數值,它指定了當TCP連接配接的資料包在發送後多長時間内未被确認(即沒有收到ACK),TCP連接配接會考慮釋放這個連接配接。

打個比方,設定TCP_USER_TIMEOUT後,應用程式就可以指定說:“如果在30秒内我發送的資料沒有得到确認,那我就認定網絡連接配接出了問題,不再嘗試繼續發送,而是直接斷開連接配接。”這對于確定連接配接品質和維護使用者體驗是非常有幫助的。

在Linux中,可以使用setsockopt函數來設定某個特定socket的 TCP_USER_TIMEOUT值:

int timeout = 30000; // 30 seconds
setsockopt(sock, IPPROTO_TCP, TCP_USER_TIMEOUT, (char *)&timeout, sizeof(timeout));           

在這行代碼中,sock是已經established的TCP socket,我們将該socket的 TCP_USER_TIMEOUT設定為30000毫秒,也就是30秒。如果設定成功,這個TCP連接配接在發送資料包後30秒内如果沒有收到ACK确認,将開始進行TCP連接配接的釋放流程。

TCP_USER_TIMEOUT相較SocketTimeout可以做到更精确(不影響慢查詢),SocketTimeout逾時是不區分ACK還是請求響應時間的,但是TCP_USER_TIMEOUT要求下層的API、OS都支援。比如JDK不支援TCP_USER_TIMEOUT,但是Netty架構自己搞了Native[3]來實作對TCP_USER_TIMEOUT以及其它OS參數的設定,在這些基礎上Redis的Java用戶端lettuce依賴了Netty,是以也可以設定TCP_USER_TIMEOUT[4]。

原本我是想在Druid上提個feature來支援TCP_USER_TIMEOUT,這樣集團絕大部分業務都可以無感覺解決掉這個問題,但查下來發現JDK不支援設定這個值,想要在Druid裡面實作設定TCP_USER_TIMEOUT的話,得像Netty一樣走Native繞過JDK 來設定,這對Druid而言有點重了。

ConnectTimeout

這個值是針對新連接配接建立逾時時間設定,一般設定3-5秒就夠長了。

連接配接池

建議參考這篇《資料庫連接配接池配置推薦》[5]這篇裡的很多建議也适合業務、應用等,你把資料庫看成一個普通服務就好了解了。

補充下如果用的是Druid資料庫連接配接池不要用它來設定你的SocketTimeout參數,因為他有bug導緻你覺得設定了但實際沒設定上,2024-03-16号的1.2.22[6]這個Release才fix,是以強烈建議你講SocketTimeout寫死在JDBC URL中簡單明了。

OS兜底

假如業務是一個AP查詢/一次慢請求,一次查詢/請求就是需要半個小時,将 SocketTimeout設定太小影響正常的查詢,那麼可以将如下OS參數改小,從OS層面進行兜底。

net.ipv4.tcp_retries2 = 8

net.ipv4.tcp_syn_retries = 4           

keepalive

keepalive預設7200秒太長了,建議改成20秒,可以在OS鏡像層面固化,然後各個業務可以patch自己的值;

如果一條連接配接限制超過900秒LVS就會Reset這條連接配接,但是我們将keepalive設定小于900秒的話,即使業務上一直閑置,因為有keepalive觸發心跳包,讓LVS不至于Reset,這也就避免了當業務取連接配接使用的時候才發現連接配接已經不可用被斷開了,往往這個時候業務抛錯誤的時間很和真正Reset時間還差了很多,不好排查。

在觸發TCP retransmission後會停止keepalive探測。

LVS

如果你們試用了aliyun的SLB,當摘除節點的時候支援你設定一個時間,過了這個時間aliyun的SLB就會向這些連接配接的用戶端發Reset幹掉這些流量,讓用戶端觸發建立連接配接,從故障中快速恢複,這是一個執行個體次元的參數,建議雲上所有産品都支援起來,管控可以在購買aliyun的SLB的時候設定一個預設值:

connection_drain_timeout

其它

神奇的900秒

上面闡述的長連接配接流量黑洞一般是900+秒就恢複了,有時候我們經常在日志中看到 CommunicationsException:Communications link failure 900秒之類的錯誤,恰好LVS也是設定的900秒閑置Reset。

#ipvsadm -L --timeout

Timeout (tcp tcpfin udp): 900 120 300           

為什麼這個問題這幾年才明顯暴露

  • 工程師們混沌了幾十年;
  • 之前因為出現頻率低重新開機業務就糊弄過去了;
  • 對新連接配接不存在這個問題;
  • 有些連接配接池配置了Check機制(Check機制一般幾秒鐘逾時fail);
  • 微服務多了;
  • 雲上LVS普及了;
  • k8s service大行其道;

我用的7層是不是就沒有這個問題了?

幼稚,你4層都挂了7層還能蹦跶,再說一遍隻要是TCP長連接配接就有這個問題。

極端情況

A長連接配接通路B服務,B服務到A網絡不通,假如B發生HA,一般會先Reset/斷開B上所有連接配接(比如MySQL會去kill所有processlist;比如重新開機MySQL——假如這裡的B是MySQL),但是因為網絡不通這裡的reset、fin網絡包都無法到達A,是以B是無法兜底這個異常場景,A無法感覺B不可用了,會使用舊連接配接大約15分鐘。

最可怕的是B服務不響應,B所在的OS還在響應,那麼在A的視角網絡是正常的,這時隻能A自己來通過逾時兜底。

總結

這種問題在LVS場景下暴露更明顯了,但是又和LVS沒啥關系,任何業務長連接配接都會導緻這個900秒左右的流量黑洞,首先要在業務層面重視這個問題,要不以後資料庫一挂掉還得重新開機業務才能從故障中将恢複,是以業務層面處理好了可以避免900秒黑洞和重新開機業務,達到快速從故障中恢複。

再強調下這個問題如果去掉LVS/k8s Service/軟負載等讓兩個服務直連,然後拔網線也會同樣出現。

最佳實踐總結:

  • 如果你的業務支援設定SocketTimeout那麼請一定要設定,但不一定适合分析類就是需要長時間傳回的請求;
  • 最好的方式是設定OS層面的TCP_USER_TIMEOUT參數,隻要長時間沒有ack就報錯傳回,但JDK不支援直接設定;
  • 如果用了ALB/SLB就一定要配置connection_drain_timeout這個參數;
  • OS鏡像層面也可以将tcp_retries2設定為5-10次做一個兜底;
  • 對你的逾時時間做到可控、可預期;

相關故障和資料:

ALB黑洞問題詳述:《為什麼Lettuce會帶來更長的故障時間?》

資料庫故障引發的“血案”:https://www.cnblogs.com/nullllun/p/15073022.html這篇描述較細緻,推薦看看。

tcp_retries2的解釋:

tcp_retries1 - INTEGER

    This value influences the time, after which TCP decides, that

    something is wrong due to unacknowledged RTO retransmissions,

    and reports this suspicion to the network layer.

    See tcp_retries2 for more details.




    RFC 1122 recommends at least 3 retransmissions, which is the

    default.




tcp_retries2 - INTEGER

    This value influences the timeout of an alive TCP connection,

    when RTO retransmissions remain unacknowledged.

    Given a value of N, a hypothetical TCP connection following

    exponential backoff with an initial RTO of TCP_RTO_MIN would

    retransmit N times before killing the connection at the (N+1)th RTO.




    The default value of 15 yields a hypothetical timeout of 924.6

    seconds and is a lower bound for the effective timeout.

    TCP will effectively time out at the first RTO which exceeds the

    hypothetical timeout.




    RFC 1122 recommends at least 100 seconds for the timeout,

    which corresponds to a value of at least 8.           

tcp_retries2預設值為15,根據RTO的值來決定,相當于13-30分鐘(RFC1122規定,必須大于100秒),但是這是很多年前的拍下來古董參數值,現在網絡條件好多了,個人認為改成5-10是比較恰當azure建議:https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-best-practices-connection

Oracle RAC的建議值是3:https://access.redhat.com/solutions/726753

參考連結:

[1]https://datatracker.ietf.org/doc/html/rfc5482

[2]https://github.com/torvalds/linux/commit/dca43c75e7e545694a9dd6288553f55c53e2a3a3

[3]https://github.com/tomasol/netty/commit/3010366d957d7b8106e353f99e15ccdb7d391d8f#diff-a998f73b7303461ca171432d10832884c6e7b0955d9f5634b9a8302b42a4706c

[4]https://github.com/redis/lettuce/pull/2499

[5]https://help.aliyun.com/document_detail/181399.html

[6]https://github.com/alibaba/druid/releases/tag/1.2.22

來源-微信公衆号:阿裡雲開發者

出處:https://mp.weixin.qq.com/s/VSRU_VtR7NDiSnNod-7u1g