linux 出現open many files問題 socket未正確關閉

最近網關服務器系統頻發soket客戶端連接自動斷開且 無法再進行通信,開始沒有太過深入調查 重啓網關既恢復了,但另一天又重複出現,懷疑是不是有線程死鎖導致socketserver 服務阻塞,所以仔細分析了下問題, 過程如下:

1. 首先netstat -apn PID |grep port 發現情況:


大量的連接都處於CLOSED_WAIT狀態 懷疑服務端沒有正常關閉客戶端連接。

2.然後jstack pid (jstack 生成當時jvm線程的狀態及運行情況) 發現並沒有異常信息 ,沒有線程處於異常狀態。

3.用top -Hp pid 查詢進程下所有線程的運行情況(shift+p 按cpu排序,shift+m 按內存排序)

沒有CUP使用很高的線程。

綜上的調查及連接端口close_wait查閱資料發現 linux 打開文件的句柄/socket是有限制的,通過ulimit -a 發現


最大打開文件句柄數是1024,分析是socket最大連接數超過1024 ,但系統連接的客戶端最大600,怎麼可能超過1024呢,而且連接出現close_wait 狀態,證明連接並未被關閉。

在socket全雙工通信過程中有如下幾種狀態:


   LISTEN - 偵聽來自遠方TCP端口的連接請求; 
   SYN-SENT -在發送連接請求後等待匹配的連接請求; 
   SYN-RECEIVED - 在收到和發送一個連接請求後等待對連接請求的確認; 
   ESTABLISHED- 代表一個打開的連接,數據可以傳送給用戶; 
   FIN-WAIT-1 - 等待遠程TCP的連接中斷請求,或先前的連接中斷請求的確認;
   FIN-WAIT-2 - 從遠程TCP等待連接中斷請求; 
   CLOSE-WAIT - 等待從本地用戶發來的連接中斷請求; 
   CLOSING -等待遠程TCP對連接中斷的確認; 
   LAST-ACK - 等待原來發向遠程TCP的連接中斷請求的確認; 
   TIME-WAIT -等待足夠的時間以確保遠程TCP接收到連接中斷請求的確認; 
   CLOSED - 沒有任何連接狀態;


原因分析:在TCP/IP協議中,TCP提供可靠的連接服務,連接採用三次握手建立,由於連接是全雙工的,關閉連接時,每個方向都要單獨關閉,連接拆除需要發送來回共發送四個包,因此叫做四次揮手,任何一個過程中途沒接受到消息都會停留在某一個狀態,很明顯目前大部分連接停留在close_wait 狀態,等待超時讀取時間關閉,一旦超時過長或未設置  併發量過大就容易導致客戶端連接數過大,超過linux 設置的open_files ,就導致端口被佔滿,發生 many open files無法通信。

解決辦法:

a) 修改linux open files 參數爲65535

 查詢linux open file參數命令 :ulimit -a

 修改參數方法:

 1)ulimit -n 65536 修改當前會話的 open files 參數 只能臨時改動參數  重新登錄參數失效

 2)使用ROOT 用戶登  修改文件/etc/security/limits.conf 添加:

xxx - nofile  65535
xxx 是一個用戶,如果是想所有用戶生效的話換成 * ,設置的數值與硬件配置有關,別設置太大了。

b) 設置socket讀取超時關閉時間或者更短 socket.setTimeout(3000);

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