linux TIME_WAIT 相關參數:前端
net.ipv4.tcp_tw_reuse = 0 表示開啓重用。容許將TIME-WAIT sockets從新用於新的TCP鏈接,默認爲0,表示關閉 net.ipv4.tcp_tw_recycle = 0 表示開啓TCP鏈接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉 net.ipv4.tcp_fin_timeout = 60 表示若是套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間(可改成30,通常來講FIN-WAIT-2的鏈接也極少)
注意:linux
- 不像Windows 能夠修改註冊表修改2MSL 的值,linux 是沒有辦法修改MSL的,tcp_fin_timeout 不是2MSL 而是Fin-WAIT-2狀態.數據庫
- tcp_tw_reuse 和SO_REUSEADDR 是兩個徹底不一樣的東西後端
查看參數:bash
cat/proc/sys/net/ipv4/tcp_tw_recycle (表示開啓重用。容許將TIME-WAIT sockets從新用於新的TCP鏈接,默認爲0,表示關閉)服務器
cat /proc/sys/net/ipv4/tcp_tw_reuse
修改參數:
sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse'
sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle'網絡
1. tw_reuse,tw_recycle 必須在客戶端和服務端timestamps 開啓時才管用(默認打開)socket
2. tw_reuse 只對客戶端起做用,開啓後客戶端在1s內回收tcp
3. tw_recycle 對客戶端和服務器同時起做用,開啓後在 3.5*RTO 內回收,RTO 200ms~ 120s 具體時間視網絡情況。優化
內網情況比tw_reuse 稍快,公網尤爲移動網絡大多要比tw_reuse 慢,優勢就是可以回收服務端的TIME_WAIT數量
對於客戶端
1. 做爲客戶端由於有端口65535問題,TIME_OUT過多直接影響處理能力,打開tw_reuse 便可解決,不建議同時打開tw_recycle,幫助不大。
2. tw_reuse 幫助客戶端1s完成鏈接回收,基本可實現單機6w/s請求,須要再高就增長IP數量吧。
3. 若是內網壓測場景,且客戶端不須要接收鏈接,同時tw_recycle 會有一點點好處。
4. 業務上也能夠設計由服務端主動關閉鏈接
對於服務端
1. 打開tw_reuse無效
2. 線上環境 tw_recycle 不要打開
服務器處於NAT 負載後,或者客戶端處於NAT後(這是必定的事情,基本公司家庭網絡都走NAT);
公網服務打開就可能形成部分鏈接失敗,內網的話到時能夠視狀況打開;
像我所在公司對外服務都放在負載後面,負載會把timestamp 都給清空,好吧,就算你打開也不起做用。
3. 服務器TIME_WAIT 高怎麼辦
不像客戶端有端口限制,處理大量TIME_WAIT Linux已經優化很好了,每一個處於TIME_WAIT 狀態下鏈接內存消耗不多,
並且也能經過tcp_max_tw_buckets = 262144 配置最大上限,現代機器通常也不缺這點內存。
下面像咱們一臺每秒峯值1w請求的http 短鏈接服務,長期處於tw_buckets 溢出狀態,
tw_socket_TCP 佔用70M, 由於業務簡單服務佔用CPU 200% 運行很穩定。
slabtop
262230 251461 95% 0.25K 17482 15 69928K tw_sock_TCP
ss -s Total: 259 (kernel 494) TCP: 262419 (estab 113, closed 262143, orphaned 156, synrecv 0, timewait 262143/0), ports 80 Transport Total IP IPv6 * 494 - - RAW 1 1 0 UDP 0 0 0 TCP 276 276 0 INET 277 277 0 FRAG 0 0 0
惟一不爽的就是:
系統日誌中overflow 錯誤一直再刷屏,也許該buckets 調大一下了
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
TCP: time wait bucket table overflow
5. 業務上也能夠設計由客戶端主動關閉鏈接
原理分析
1. MSL 由來
發起鏈接關閉方回覆最後一個fin 的ack,爲避免對方ack 收不到、重發的或還在中間路由上的fin 把新鏈接給幹掉了,等個2MSL,4min。
也就是鏈接有誰關閉的那一方有time_wait問題,被關那方無此問題。
2. reuse、recycle
經過timestamp的遞增性來區分是否新鏈接,新鏈接的timestamp更大,那麼小的timestamp的fin 就不會fin掉新鏈接。
3. reuse
經過timestamp 遞增性,客戶端、服務器可以處理outofbind fin包
4. recycle
對於服務端,同一個src ip,可能會是NAT後不少機器,這些機器timestamp遞增性無可保證,服務器會拒絕非遞增請求鏈接。
細節之處還得好好閱讀tcp 協議棧源碼了
【案例分析1】
最近發現幾個監控用的腳本在鏈接監控數據庫的時候偶爾會連不上,報錯:
Couldn't connect to host:3306/tcp: IO::Socket::INET: connect: Cannot assign requested address
查看了一下發現系統中存在大量處於TIME_WAIT狀態的tcp端口
$netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 50013
ESTABLISHED 27
SYN_RECV 1
因爲要監控的主機太多,監控的agent可能在短期內建立大量鏈接到監控數據庫(MySQL)並釋放形成的。在網上查閱了一些tcp參數的相關資料,最後經過修改了幾個系統內核的tcp參數緩解了該問題:
#vi /etc/sysctl.conf
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
#sysctl -p
其中:
net.ipv4.tcp_tw_reuse = 1 表示開啓重用。容許將TIME-WAIT sockets從新用於新的TCP鏈接,默認爲0,表示關閉;
net.ipv4.tcp_tw_recycle = 1 表示開啓TCP鏈接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉。
修改完成並生效後,系統中處於TIME_WAIT狀態的tcp端口數量迅速降低到100左右:
$netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
TIME_WAIT 82
ESTABLISHED 36
簡單記錄於此,備忘。
【案例分析2】
網上的帖子,大多都寫開啓net.ipv4.tcp_tw_recycle這個開關,能夠快速回收處於TIME_WAIT狀態的socket(針對Server端而言)。
而實際上,這個開關,須要net.ipv4.tcp_timestamps(默認開啓的)這個開關開啓纔有效果。
更不爲提到卻很重要的一個信息是:當tcp_tw_recycle開啓時(tcp_timestamps同時開啓,快速回收socket的效果達到),對於位於NAT設備後面的Client來講,是一場災難——會導到NAT設備後面的Client鏈接Server不穩定(有的Client能鏈接server,有的Client不能鏈接server)。也就是說,tcp_tw_recycle這個功能,是爲「內部網絡」(網絡環境本身可控——不存在NAT的狀況)設計的,對於公網,不宜使用。
一般,「回收」TIME_WAIT狀態的socket是由於「沒法主動鏈接遠端」,由於無可用的端口,而不該該是要回收內存(沒有必要)。即,需求是「Client」的需求,Server會有「端口不夠用」的問題嗎?除非是前端機,須要大量的鏈接後端服務——即充當着Client的角色。正確的解決這個老是辦法應該是:net.ipv4.ip_local_port_range = 9000 6553 #默認值範圍較小net.ipv4.tcp_max_tw_buckets = 10000 #默認值較小,還可適當調小net.ipv4.tcp_tw_reuse = 1 #net.ipv4.tcp_fin_timeout = 10 #--------------------- 做者:天府雲創 來源:CSDN 原文:https://blog.csdn.net/enweitech/article/details/79261439 版權聲明:本文爲博主原創文章,轉載請附上博文連接!