近段時間線上環境出現了CLOSE_WAIT過多,Jetty伺服器無響應(假死情況)。關于CLOSE_WAIT的說明,網上的問診有很多,這裡列兩個位址,有興趣的可以浏覽檢視:
https://huoding.com/2016/01/19/488
https://www.cnblogs.com/kevin-wu/archive/2006/11/27/574369.html
一開始,記錄到的資訊隻有網絡方面的資料,包括并發數和網絡參數,如下:
321(項目的并發數)
TIME_WAIT 533
CLOSE_WAIT 970
FIN_WAIT1 25
FIN_WAIT2 46
ESTABLISHED 592
SYN_RECV 9
CLOSING 1
LAST_ACK 5
其中第一個資料的記錄指令為:netstat -an |grep ‘ESTABLISHED’ |grep -i ‘7901’ |wc -l (其中7901是web伺服器端口)
第二個資料的記錄指令為:netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}’
當然這部分的資料,也可以用Zabbix監控,圖形界面,更友善檢視和分析。
根據網上的資料,大部分都是調整Linux網絡參數,主要是以下三個:(可以參考http://lvxuehu.iteye.com/blog/452487)
net.ipv4.tcp_keepalive_time=60
net.ipv4.tcp_keepalive_probes=3
net.ipv4.tcp_keepalive_intvl=3
修改這些參數,隻能治标不能治本。
後面想到的是通過java的工具,檢視出現問題時的堆棧資訊。結果發現線上的伺服器并沒有jstack指令,排查發現原來的運維裝的是jre,而不是jdk(汗)。完美的錯過了一次記錄出現問題資訊的記錄。最後通過指令:jstack -l 9430 記錄當時的堆棧資訊。問題出在有一個地方處理慢,在最外層有影響全局的大鎖。所有的處理都處理等待情況,出現阻塞。
總結:出現線上故障時,盡可能多的記錄當時的資訊,有利于後面定位排查問題,解決的方法才能處理到點上。
CLOSE_WAIT問題根源還是在伺服器上,需要從自己的代碼入手。