TCP/IP TIME_WAIT 問題小結

最近公司業(yè)務線上經常報TIME_WAIT的連接數(shù)過多的問題,多方查閱資料,在這里總結有關TIME_WAIT的問題。

TIME_WAIT 是啥?

我們常見的TCP連接多數(shù)為短連接。TCP建立連接需要三次握手,斷開連接需要四次揮手。而這個TIME_WAIT就是出現(xiàn)在斷開連接的四次揮手過程中,還是先看下TCP四次揮手。


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è)務類型不同加以選擇。

  1. 短連接變長連接,減少連接數(shù)量。
  2. echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout 縮短timeout的時間
  3. echo 15000 65000 > /proc/sys/net/ipv4/ip_local_port_range 擴大可用端口范圍,當然這里需要注意端口沖突的問題。
  4. 啟用tcp_tw_recycle 和 tcp_tw_reuse,這個方式不推薦。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容