記一次CLOSE_WAIT多的故障

問題:

Cannot send, channel has already failed: tcp://ip:61616
javax.jms.JMSException: Cannot send, channel has already failed: tcp://ip:61616

應用連不上mq

解決方案:

一,分析思路:

1.現象:通過netstat 查看與61616相關的連接狀況,發現130多個CLOSE_WAIT

2.是什麼原因造成這麼多的CLOSE_WAIT?

2.1 主要原因是某種情況下應用關閉了socket連接,但是mq忙於讀或者寫,沒有關閉連接.

2.2 代碼需要判斷socket,一旦讀到0,斷開連接,read返回負,檢查一下errno,如果不是AGAIN,就斷開連接。

3.造成CLOSE_WAIT之後服務爲啥連不上mq呢?

linux分配給一個用戶的文件句柄是有限的,CLOSE_WAIT狀態一直被保持,意味着對應數目的通道就一直被佔着,一旦達到句柄數上線,新的請求就無法被處理了,應用程序可能會返回大量的Too many openfiles異常.

4.什麼是CLOSE_WAIT?

4.1 mq爲被連接端,java服務爲主動方,在被動關閉情況下,mq已經接收到FIN,但是還沒有發送自己的FIN的時刻,連接處於CLOSE_WAIT狀態;

二,解決辦法:

1.重啓mq

2,linux下設置如下三個參數:

/proc/sys/net/ipv4/tcp_keepalive_time當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時。

/proc/sys/net/ipv4/tcp_keepalive_intvl當探測沒有確認時,重新發送探測的頻度。缺省是75秒。

/proc/sys/net/ipv4/tcp_keepalive_probes在認定連接失效之前,發送多少個TCP的keepalive探測包。缺省值是9。這個值乘以tcp_keepalive_intvl之後決定了,一個連接發送了keepalive之後可以有多少時間沒有迴應。

三.瞭解擴展

1.客戶端先發送FIN,進入FIN_WAIT1狀態

服務端收到FIN,發送ACK,進入CLOSE_WAIT狀態,客戶端收到這個ACK,進入FIN_WAIT2狀態
服務端發送FIN,進入LAST_ACK狀態
客戶端收到FIN,發送ACK,進入TIME_WAIT狀態,服務端收到ACK,進入CLOSE狀態
客戶端TIME_WAIT持續2倍MSL時長,在linux體系中大概是60s,轉換成CLOSE狀態

2.服務端使用的短鏈接,每次客戶端請求後,服務端都會主動發送FIN關閉連接.最後進入到time_wait狀態.對於訪問量大的web server,會存在大量的TIME_WAIT狀態.讓服務器能夠快速回收和重用那些TIME_WAIT的資源,可修改內核參數.

修改/etc/sysctl.conf如下:
#對於一個新建連接,內核要發送多少個 SYN 連接請求才決定放棄,不應該大於255,默認值是5,對應於180秒左右時間
net.ipv4.tcp_syn_retries=2
#表示當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時,改爲300秒
net.ipv4.tcp_keepalive_time=1200

net.ipv4.tcp_orphan_retries=3
#表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間
net.ipv4.tcp_fin_timeout=30
#表示SYN隊列的長度,默認爲1024,加大隊列長度爲8192,可以容納更多等待連接的網絡連接數。
net.ipv4.tcp_max_syn_backlog = 4096
#表示開啓SYN Cookies。當出現SYN等待隊列溢出時,啓用cookies來處理,可防範少量SYN***,默認爲0,表示關閉
net.ipv4.tcp_syncookies = 1

#表示開啓重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認爲0,表示關閉
net.ipv4.tcp_tw_reuse = 1
#表示開啓TCP連接中TIME-WAIT sockets的快速回收,默認爲0,表示關閉
net.ipv4.tcp_tw_recycle = 1

##減少超時前的探測次數
net.ipv4.tcp_keepalive_probes=5
##優化網絡設備接收隊列
net.core.netdev_max_backlog=3000
修改完之後執行/sbin/sysctl -p讓參數生效。

相關文章:
http://vinc.top/2016/08/22/time_wait%E5%92%8Cclose_wait%E4%BA%A7%E7%94%9F%E5%8E%9F%E5%9B%A0%E5%8F%8A%E8%A7%A3%E5%86%B3/

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