最近公司業(yè)務線上經常報TIME_WAIT的連接數(shù)過多的問題,多方查閱資料,在這里總結有關TIME_WAIT的問題。
TIME_WAIT 是啥?
我們常見的TCP連接多數(shù)為短連接。TCP建立連接需要三次握手,斷開連接需要四次揮手。而這個TIME_WAIT就是出現(xiàn)在斷開連接的四次揮手過程中,還是先看下TCP四次揮手。
1:Clinet客戶端主動發(fā)起關閉請求,向Server服務端send FIN。
2:服務端收到FIN,向客戶端ACK確認請求。
3:服務端關閉連接準備就緒,向客戶端發(fā)送FIN。
4:同樣的客戶端收到FIN也向服務端發(fā)送ACK確認請求。
當?shù)谒牟娇蛻舳藄end ACK之后就進入了TIME_WAIT狀態(tài)。之所以出現(xiàn)TIME_WAIT,也是出自于考慮連接的可靠性。
假如TCP連接這個時候直接進入CLOSED狀態(tài),只要服務端沒有收到ACK就會導致重新發(fā)送FIN,原來連接已經CLOSED,客戶端會返回RST包用于強制關閉TCP連接,而且這個FIN也有可能影響其他的連接,這樣一來,TCP連接就變得不可靠了,所以這個TIME_WAIT有存在的必要。
從圖上來看都是客戶端進入TIME_WAIT狀態(tài),為啥服務端的監(jiān)控會出現(xiàn)TIME_WAIT報警呢?其實TIME_WAIT狀態(tài)總是出現(xiàn)在主動發(fā)起關閉連接的一方。當然這里的客戶端、服務端也都是相對的概念。服務端當然也會有場景去擔當客戶端,比如去連接數(shù)據(jù)庫,連接緩存等等,這時候服務端擔任的角色恰好就是"客戶端"。這也就是服務端經常會報TIME_WAIT連接數(shù)的原因了。
當服務端作為客戶端發(fā)起TCP連接的時候,是需要占用本地的端口號的。在Linux系統(tǒng)中,我們通過cat /proc/sys/net/ipv4/ip_local_port_range
指令可以查看系統(tǒng)可分配的端口總數(shù),Linux默認的端口范圍:32768~61000
,共計28232個可用端口。同樣我們可以通過cat /proc/sys/net/ipv4/tcp_fin_timeout
查看tcp連接默認的timeout時長,Linux默認的timeout時間是60
秒。由此可見服務器向外發(fā)送連接每秒最多大約470個端口可供使用。當我們需要每秒建立大量的連接的時候,就會受限于此。
調優(yōu)
對于調優(yōu)方案來說,我認為沒有最好的方案,只有最合適的方案,可以根據(jù)業(yè)務類型不同加以選擇。
- 短連接變長連接,減少連接數(shù)量。
-
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
縮短timeout的時間 -
echo 15000 65000 > /proc/sys/net/ipv4/ip_local_port_range
擴大可用端口范圍,當然這里需要注意端口沖突的問題。 - 啟用tcp_tw_recycle 和 tcp_tw_reuse,這個方式不推薦。