https://www.cnblogs.com/sunxucool/p/3449068.html
查看網絡連接數:
netstat -an |wc -l
netstat -an |grep xx |wc -l 查看某個/特定ip的連接數
netstat -an |grep TIME_WAIT|wc -l 查看連接數等待time_wait狀態連接數
netstat -an |grep ESTABLISHED |wc -l 查看建立穩定連接數量
查看不同狀態的連接數數量
[root@cp-nginx ~]# netstat -an | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'
LISTEN 8
ESTABLISHED 2400
FIN_WAIT1 2
TIME_WAIT 6000
查看每個ip跟服務器建立的連接數
[root@cp-nginx ~]# netstat -nat|awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn
31 45.116.147.178
20 45.116.147.186
12 23.234.45.34
11 103.56.195.17
(PS:正則解析:顯示第5列,-F : 以:分割,顯示列,sort 排序,uniq -c統計排序過程中的重復行,sort -rn 按純數字進行逆序排序)
查看每個ip建立的ESTABLISHED/TIME_OUT狀態的連接數
[root@cp-nginx ~]# netstat -nat|grep ESTABLISHED|awk '{print$5}'|awk -F : '{print$1}'|sort|uniq -c|sort -rn
24 103.56.195.17
19 45.116.147.186
18 103.56.195.18
17 45.116.147.178
問題1:解決time_wait連接數大量問題
查詢到time_wait連接數過多情況下,調整內核參數:/etc/sysctl.conf
vim /etc/sysctl.conf
添加以下配置文件:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 300
/sbin/sysctl -p 讓參數生效,調優完成
參數詳解:
1.net.ipv4.tcp_syncookies = 1 表示開啟 syn cookies 。當出現 syn 等待隊列溢出時,啟用 cookies 來處理,可防范少量 syn ***,默認為 0 ,表示關閉;
2.net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將 time-wait sockets 重新用於新的 tcp 連接,默認為 0 ,表示關閉;
3.net.ipv4.tcp_tw_recycle = 1 表示開啟 tcp 連接中 time-wait sockets 的快速回收,默認為 0 ,表示關閉。
4.net.ipv4.tcp_fin_timeout 修改系靳默認的 timeout 時間
如果以上配置調優后性能還不理想,可繼續修改一下配置:
vi /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 1200 #表示當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時,改為20分鍾。 net.ipv4.ip_local_port_range = 1024 65000 #表示用於向外連接的端口范圍。缺省情況下很小:32768到61000,改為1024到65000。 net.ipv4.tcp_max_syn_backlog = 8192 #表示SYN隊列的長度,默認為1024,加大隊列長度為8192,可以容納更多等待連接的網絡連接數。 net.ipv4.tcp_max_tw_buckets = 5000 #表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並打印警告信息。 默認為180000,改為5000。 對於Apache、Nginx等服務器,上幾行的參數可以很好地減少TIME_WAIT套接字數量,但是對於 Squid,效果卻不大。此項參數可以控制TIME_WAIT套接字的最大數量,避免Squid服務器被大量的TIME_WAIT套接字拖死。
問題2:ESTABLISHED連接數過大問題
怎么解決請求結束后依然存在大量ESTABLISHED沒有被釋放
初步推斷是tomcat服務器回收session時出了問題,這個一般都跟服務器的Timeout設置有聯系。
查看tomcat的配置文件 server.xml
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
*****
檢查配置得出20000毫秒的時候acceptCount=”100” ,明顯不合理,最大連接數也太小了吧。
所以進一步優化:
connectionTimeout="20000" 改為 connectionTimeout="100" acceptCount="100"改為acceptCount="5000"
優化完畢,繼續壓測...
系統響應能力節節攀升,之前LoadRunner報錯問題直到壓倒***並發也再也沒有出現。
Action.c(380): 錯誤 -26608: 對於“http://www.cnlogs.com/javame”,HTTP 狀態代碼=504 (Gateway Time-out)
昨天解決了一個HttpClient調用錯誤導致的服務器異常,具體過程如下:
http://blog.csdn.net/shootyou/article/details/6615051
里頭的分析過程有提到,通過查看服務器網絡狀態檢測到服務器有大量的CLOSE_WAIT的狀態。
在服務器的日常維護過程中,會經常用到下面的命令:
- netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
它會顯示例如下面的信息:
TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1
常用的三個狀態是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。
具體每種狀態什么意思,其實無需多說,看看下面這種圖就明白了,注意這里提到的服務器應該是業務請求接受處理的一方:
這么多狀態不用都記住,只要了解到我上面提到的最常見的三種狀態的意義就可以了。一般不到萬不得已的情況也不會去查看網絡狀態,如果服務器出了異常,百分之八九十都是下面兩種情況:
1.服務器保持了大量TIME_WAIT狀態
2.服務器保持了大量CLOSE_WAIT狀態
因為linux分配給一個用戶的文件句柄是有限的(可以參考:http://blog.csdn.net/shootyou/article/details/6579139),而TIME_WAIT和CLOSE_WAIT兩種狀態如果一直被保持,那么意味着對應數目的通道就一直被占着,而且是“占着茅坑不使勁”,一旦達到句柄數上限,新的請求就無法被處理了,接着就是大量Too Many Open Files異常,tomcat崩潰。。。
下 面來討論下這兩種情況的處理方法,網上有很多資料把這兩種情況的處理方法混為一談,以為優化系統內核參數就可以解決問題,其實是不恰當的,優化系統內核參 數解決TIME_WAIT可能很容易,但是應對CLOSE_WAIT的情況還是需要從程序本身出發。現在來分別說說這兩種情況的處理方法:
1.服務器保持了大量TIME_WAIT狀態
這種情況比較常見,一些爬蟲服務器或者WEB服務器(如果網管在安裝的時候沒有做內核參數優化的話)上經常會遇到這個問題,這個問題是怎么產生的呢?
從 上面的示意圖可以看得出來,TIME_WAIT是主動關閉連接的一方保持的狀態,對於爬蟲服務器來說他本身就是“客戶端”,在完成一個爬取任務之后,他就 會發起主動關閉連接,從而進入TIME_WAIT的狀態,然后在保持這個狀態2MSL(max segment lifetime)時間之后,徹底關閉回收資源。為什么要這么做?明明就已經主動關閉連接了為啥還要保持資源一段時間呢?這個是TCP/IP的設計者規定 的,主要出於以下兩個方面的考慮:
1.防止上一次連接中的包,迷路后重新出現,影響新連接(經過2MSL,上一次連接中所有的重復包都會消失)
2. 可靠的關閉TCP連接。在主動關閉方發送的最后一個 ack(fin) ,有可能丟失,這時被動方會重新發fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。另外這么設計TIME_WAIT 會定時的回收資源,並不會占用很大資源的,除非短時間內接受大量請求或者受到攻擊。
關於MSL引用下面一段話:
- MSL 為 一個 TCP Segment (某一塊 TCP 網路封包) 從來源送到目的之間可續存的時間 (也就是一個網路封包在網路上傳輸時能存活的時間),由 於 RFC 793 TCP 傳輸協定是在 1981 年定義的,當時的網路速度不像現在的網際網路那樣發達,你可以想像你從瀏覽器輸入網址等到第一 個 byte 出現要等 4 分鐘嗎?在現在的網路環境下幾乎不可能有這種事情發生,因此我們大可將 TIME_WAIT 狀態的續存時間大幅調低,好 讓 連線埠 (Ports) 能更快空出來給其他連線使用。
再引用網絡資源的一段話:
- 值 得一說的是,對於基於TCP的HTTP協議,關閉TCP連接的是Server端,這樣,Server端會進入TIME_WAIT狀態,可 想而知,對於訪 問量大的Web Server,會存在大量的TIME_WAIT狀態,假如server一秒鍾接收1000個請求,那么就會積壓 240*1000=240,000個 TIME_WAIT的記錄,維護這些狀態給Server帶來負擔。當然現代操作系統都會用快速的查找算法來管理這些 TIME_WAIT,所以對於新的 TCP連接請求,判斷是否hit中一個TIME_WAIT不會太費時間,但是有這么多狀態要維護總是不好。
- HTTP協議1.1版規定default行為是Keep-Alive,也就是會重用TCP連接傳輸多個 request/response,一個主要原因就是發現了這個問題。
也就是說HTTP的交互跟上面畫的那個圖是不一樣的,關閉連接的不是客戶端,而是服務器,所以web服務器也是會出現大量的TIME_WAIT的情況的。
- #對於一個新建連接,內核要發送多少個 SYN 連接請求才決定放棄,不應該大於255,默認值是5,對應於180秒左右時間
- net.ipv4.tcp_syn_retries=2
- #net.ipv4.tcp_synack_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
net.ipv4.tcp_fin_timeout
net.ipv4.tcp_keepalive_*
近期服務器出現大量time_wait的TCP連接造成服務器連接數過多而最終導致tomcat假死狀態。連接服務器查看連接數的時候提示如下。
-
[root@test apache-tomcat-7.0.53]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
-
TIME_WAIT 14434
-
FIN_WAIT2 6
-
ESTABLISHED 133
很明顯可以看出是請求太多頻繁,主要由於后端服務器之間是通過rest請求相互調用的,而java服務器回收tcp線程速度比較慢,雖然已經有顯性的關閉連接了,但是實際在調
用的時候連接回收還是較慢。通過java API解決這個問題的路子就堵死了。
后來去服務器查閱了大量資料,可以考慮通過修改linux內核的方式解決此處問題。解決方法如下:
vi /etc/sysctl.conf
添加配置信息
-
#表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防范少量SYN攻擊。默認為0,表示關閉
-
net.ipv4.tcp_syncookies = 1
-
#表示開啟重用tcp連接。允許將TIME-WAIT sockets重新用於新的TCP連接。默認為0,表示關閉
-
net.ipv4.tcp_tw_reuse = 1
-
#表示開啟TCP連接中TIME-WAIT sockets的快速回收。默認為0,表示關閉
-
net.ipv4.tcp_tw_recycle = 1
-
#表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間
-
net.ipv4.tcp_fin_timeout = 30
讓參數配置生效
/sbin/sysctl -p
問題完美解決:
-
[root@test apache-tomcat-7.0.53]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
-
TIME_WAIT 96
-
FIN_WAIT2 3
-
ESTABLISHED 141
-