Linux下檢視Nginx的併發連線數和連線狀態

pythontab發表於2015-07-15

Linux下檢視Nginx等的併發連線數和連線狀態。


1、檢視Web伺服器(Nginx Apache)的併發請求數及其TCP連線狀態: 

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

或者:

netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}'返回結果一般如下: 

LAST_ACK 5 (正在等待處理的請求數)

SYN_RECV 30 

ESTABLISHED 1597 (正常資料傳輸狀態) 

FIN_WAIT1 51 

FIN_WAIT2 504 

TIME_WAIT 1057 (處理完畢,等待超時結束的請求數) 

其他引數說明: 

CLOSED:無連線是活動的或正在進行


LISTEN:伺服器在等待進入呼叫 

SYN_RECV:一個連線請求已經到達,等待確認 

SYN_SENT:應用已經開始,開啟一個連線 

ESTABLISHED:正常資料傳輸狀態 

FIN_WAIT1:應用說它已經完成 

FIN_WAIT2:另一邊已同意釋放 

ITMED_WAIT:等待所有分組死掉 

CLOSING:兩邊同時嘗試關閉 

TIME_WAIT:另一邊已初始化一個釋放 

LAST_ACK:等待所有分組死掉 


常用的三個狀態是:ESTABLISHED 表示正在通訊,TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。

TCP協議規定,對於已經建立的連線,網路雙方要進行四次握手才能成功斷開連線,如果缺少了其中某個步驟,將會使連線處於假死狀態,連線本身佔用的資源不會被釋放。網路伺服器程式要同時管理大量連線,所以很有必要保證無用連線完全斷開,否則大量僵死的連線會浪費許多伺服器資源。在眾多TCP狀態中,最值得注意的狀態有兩個:CLOSE_WAIT和TIME_WAIT。  

TIME_WAIT 

TIME_WAIT 是主動關閉連結時形成的,等待2MSL時間,約4分鐘。主要是防止最後一個ACK丟失。  由於TIME_WAIT 的時間會非常長,因此server端應儘量減少主動關閉連線

CLOSE_WAIT

CLOSE_WAIT是被動關閉連線是形成的。根據TCP狀態機,伺服器端收到客戶端傳送的FIN,則按照TCP實現傳送ACK,因此進入CLOSE_WAIT狀態。但如果伺服器端不執行close(),就不能由CLOSE_WAIT遷移到LAST_ACK,則系統中會存在很多CLOSE_WAIT狀態的連線。此時,可能是系統忙於處理讀、寫操作,而未將已收到FIN的連線,進行close。此時,recv/read已收到FIN的連線socket,會返回0。

為什麼需要 TIME_WAIT 狀態?

假設最終的ACK丟失,server將重發FIN,client必須維護TCP狀態資訊以便可以重發最終的ACK,否則會傳送RST,結果server認為發生錯誤。TCP實現必須可靠地終止連線的兩個方向(全雙工關閉),client必須進入 TIME_WAIT 狀態,因為client可能面 臨重發最終ACK的情形。

為什麼 TIME_WAIT 狀態需要保持 2MSL 這麼長的時間?

如果 TIME_WAIT 狀態保持時間不足夠長(比如小於2MSL),第一個連線就正常終止了。第二個擁有相同相關五元組的連線出現,而第一個連線的重複報文到達,干擾了第二個連線。TCP實現必須防止某個連線的重複報文在連線終止後出現,所以讓TIME_WAIT狀態保持時間足夠長(2MSL),連線相應方向上的TCP報文要麼完全響應完畢,要麼被 丟棄。建立第二個連線的時候,不會混淆。

 TIME_WAIT 和CLOSE_WAIT狀態socket過多

如果伺服器出了異常,百分之八九十都是下面兩種情況:

1.伺服器保持了大量TIME_WAIT狀態

2.伺服器保持了大量CLOSE_WAIT狀態,簡單來說CLOSE_WAIT數目過大是由於被動關閉連線處理不當導致的。


因為linux分配給一個使用者的檔案控制程式碼是有限的,而TIME_WAIT和CLOSE_WAIT兩種狀態如果一直被保持,那麼意味著對應數目的通道就一直被佔著,而且是“佔著茅坑不使勁”,一旦達到控制程式碼數上限,新的請求就無法被處理了,接著就是大量Too Many Open Files異常,Tomcat崩潰。


相關文章