關於網絡設備的FIN_WAIT_2狀態解釋出處:http://hi.baidu.com/netdemon1981/blog/item/584bfbb2aeb1d4acd9335ad9.html
在HTTP應用中,存在一個問題,SERVER因爲某種緣由關閉鏈接,如KEEPALIVE的超時,這樣,做爲主動關閉的SERVER一方就會進入 FIN_WAIT2狀態,但TCP/IP協議棧有個問題,FIN_WAIT2狀態是沒有超時的(不象TIME_WAIT狀態),因此若是CLIENT不關閉,這個FIN_WAIT_2狀態將保持到系統從新啓動,愈來愈多的FIN_WAIT_2狀態會導致內核crash。
產生緣由:
1。常鏈接而且當鏈接一直處於IDLE狀態致使SERVER CLOSE時,CLIENT編程缺陷,沒有向SERVER 發出FIN和ACK包
2。APACHE1.1和APACHE1.2增長了linger_close()函數,前面的帖子有介紹,這個函數可能引發了這個問題(爲何我也不清楚)
解決辦法:
1。對FIN_WAIT_2狀態增長超時機制,這個特性在協議裏沒有體現,但在一些OS中已經實現
如:LINUX、SOLARIS、FREEBSD、HP-UNIX、IRIX等
2。不要用linger_close()編譯
3。用SO_LINGER代替,這個在某些系統中還能很好地處理
4。增長用於存儲網絡鏈接狀態的內存mbuf,以防止內核crash
5。DISABLE KEEPALIVE
TCP FIN_WAIT_2狀態問題分析
出處:http://hi.baidu.com/huochai2020/item/eb3fc2530fb52bd6d48bace5
一、出現fin_wait_2通常爲客戶端,若是爲服務端出現,則代表是服務端主動發起的斷開。
C:\Documents and Settings\Administrator>netstat -an|findstr 10.208.8.2:
TCP 10.88.2.26:9002 10.208.8.2:1040 FIN_WAIT_2
TCP 10.88.2.26:9002 10.208.8.2:1048 FIN_WAIT_2
TCP 10.88.2.26:9002 10.208.8.2:1051 FIN_WAIT_2
TCP 10.88.2.26:9002 10.208.8.2:1052 FIN_WAIT_2
TCP 10.88.2.26:9002 10.208.8.2:1056 FIN_WAIT_2
TCP 10.88.2.26:9002 10.208.8.2:1058 FIN_WAIT_2 #netstat -an|grep 10.116.50.30
tcp 0 0 192.168.129.44.64306 10.116.50.30.53081 FIN_WAIT_2
tcp 0 0 192.168.129.44.63611 10.116.50.30.57966 FIN_WAIT_2
tcp 0 0 192.168.129.44.57835 10.116.50.30.49188 FIN_WAIT_2
tcp 0 0 192.168.129.44.57502 10.116.50.30.52615 ESTABLISHED
二、爲何發生
a.客戶端狀態遷移(主動結束鏈接)CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSEDb.服務器狀態遷移CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED 有缺陷的客戶端與持久鏈接
有一些客戶端在處理持久鏈接(aka keepalives)時存在問題。當鏈接空閒下來服務器關閉鏈接時(基於KeepAliveTimeout指令), 客戶端的程序編制使它不發送FIN和ACK回服務器。這樣就意味着這個鏈接 將停留在FIN_WAIT_2狀態直到如下之一發生:
客戶端爲同一個或者不一樣的站點打開新的鏈接,這樣會使它在該個套接字上徹底關閉之前的鏈接。
用戶退出客戶端程序,這樣在一些(也許是大多數?)客戶端上會使操做系統徹底關閉鏈接。
FIN_WAIT_2超時,在那些具備FIN_WAIT_2狀態超時設置的服務器上。
若是你夠幸運,這樣意味着那些有缺陷的客戶端會徹底關閉鏈接並釋放你服務器的資源。 然而,有一些狀況下套接字永遠不會徹底關閉,好比一個撥號客戶端在關閉客戶端程序以前從ISP斷開。 此外,有的客戶端有可能空置好幾天不建立新鏈接,而且這樣在好幾天裏保持着套接字的有效即便已經再也不使用。 這是瀏覽器或者操做系統的TCP實現的Bug。
三、如何解決
爲 FIN_WAIT_2 增長 超時機制
windows:
開始->運行->輸入regedit
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
在詳細信息窗格中雙擊 TCPFinWait2Delay ,而後從 30 到 300 中輸入一個值。
請注意 若是不存在 TCPFinWait2Delay 值,必須爲 REG _ DWORD 註冊表值來建立它。 註冊表該值控制 TCP 鏈接以前等待的秒數它被強制關閉, 關閉 (s,SD_SEND) 函數調用以後。 在默認值爲 240 秒。 此值範圍是 30 到 300。 必須手動建立此註冊表值。 不然,使用默認值。
HP-UNIX:
#ndd -set /dev/tcp tcp_fin_wait_2_timeout 60000 (1分鐘)
執行上述命令,重起系統後將失效,若是須要一致起做用,則修改下列文件:/etc/rc.config.d/nddconf
設置參數tcp_fin_wait_2_timeout值。
禁止KeepAlive
Apache:編輯你的httpd.conf並把"KeepAlive On"改成"KeepAlive Off"。
使用linger:
linger lig;
lig.l_onoff=1;
lig.l_linger=0;
int ilen=sizeof(linger);
setsockopt(Socket,SOL_SOCKET,SO_LINGER,(char*)&lig,ilen); html