Linux服務器出現大量的CLOSE_WAIT的問題

Linux服務器出現大量的CLOSE_WAIT的問題

Linux服務器tcp socket常見的幾種狀態:ESTABLISHED、TIME_WAIT、CLOSE_WAIT。

TCP協議中描述,對於已經建立的連接,網絡雙方要進行四次握手才能成功斷開連接,如果缺少了其中某個步驟,將會使連接處於假死狀態,連接本身佔用的資源不會被釋放。

提供網絡服務時,需要特別關注兩種狀態:CLOSE_WAIT和TIME_WAIT。如果過多,可能導致socket資源耗盡,無法正常提供服務。

ESTABLISHED:表示正在socket通信。

TIME_WAIT:表示請求的客戶端主動關閉socket而形成的狀態。等待2MSL時間,約4分鐘。主要是防止最後一個ACK丟失。由於TIME_WAIT的時間會非常長,因此服務端應儘量減少主動關閉連接。

之所以設計TIME_WAIT狀態,是爲了考慮ACK丟失的情況發生,服務端將重發FIN,客戶端必須維護TCP狀態信息以便可以重發最終的ACK,否則會發送RST,結果服務端認爲發生錯誤。

CLOSE_WAIT:表示服務端被動關閉socket。根據TCP狀態機,服務器端收到客戶端發送的FIN,則按照TCP實現發送ACK,因此進入CLOSE_WAIT狀態。但如果服務器端不執行close(),就不能由CLOSE_WAIT遷移到LAST_ACK,則系統中會存在很多CLOSE_WAIT狀態的連接。

我就碰到了Linux服務器出現大量的CLOSE_WAIT後,服務無法繼續正常服務,socket資源被耗盡。因爲Linux分配給一個用戶的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT兩種狀態如果一直被保持,則文件句柄也就不能close,導致句柄資源達到上線,接着就會出現大量Too Many Open Files錯誤。

如果出現大量CLOSE_WAIT,首先需要考慮程序是否有BUG,是否有socket泄露(遺漏close())。

查看當前系統中的tcp socket狀態信息:

# netstat -n | awk '/^tcp/ {++X[$NF]} END {for(i in X) print i, X[i]}'?

另外一個命令:lsof

搜索系統中IP爲192.168.100.20的遠程鏈接所有打開的套接字:

# lsof [email protected]
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章