1. 程式人生 > >Tcp連接出現大量ESTABLISHED連接解決方法

Tcp連接出現大量ESTABLISHED連接解決方法

tcp established

TCP狀態轉移要點
TCP協議規定,對於已經建立的連接,網絡雙方要進行四次握手才能成功斷開連接,如果缺少了其中某個步驟,將會使連接處於假死狀態,連接本身占用的資源不 會被釋放。網絡服務器程序要同時管理大量連接,所以很有必要保證無用連接完全斷開,否則大量僵死的連接會浪費許多服務器資源。在眾多TCP狀態中,最值得 註意的狀態有兩個:CLOSE_WAIT和TIME_WAIT。

1、LISTENING狀態
FTP服務啟動後首先處於偵聽(LISTENING)狀態。

2、ESTABLISHED狀態
ESTABLISHED的意思是建立連接。表示兩臺機器正在通信

3、CLOSE_WAIT

對方主動關閉連接或者網絡異常導致連接中斷,這時我方的狀態會變成CLOSE_WAIT 此時我方要調用close()來使得連接正確關閉

4、TIME_WAIT

我方主動調用close()斷開連接,收到對方確認後狀態變為TIME_WAIT。TCP協議規定TIME_WAIT狀態會一直持續2MSL(即兩倍的分 段最大生存期),以此來確保舊的連接狀態不會對新連接產生影響。處於TIME_WAIT狀態的連接占用的資源不會被內核釋放,所以作為服務器,在可能的情 況下,盡量不要主動斷開連接,以減少TIME_WAIT狀態造成的資源浪費。

目前有一種避免TIME_WAIT資源浪費的方法,就是關閉socket的LINGER選項。但這種做法是TCP協議不推薦使用的,在某些情況下這個操作可能會帶來錯誤。

5、SYN_SENT狀態

   SYN_SENT狀態表示請求連接,當你要訪問其它的計算機的服務時首先要發個同步信號給該端口,此時狀態為SYN_SENT,如果連接成功了就變為 ESTABLISHED,此時SYN_SENT狀態非常短暫。但如果發現SYN_SENT非常多且在向不同的機器發出,那你的機器可能中了沖擊波或震蕩波 之類的病毒了。這類病毒為了感染別的計算機,它就要掃描別的計算機,在掃描的過程中對每個要掃描的計算機都要發出了同步請求,這也是出現許多 SYN_SENT的原因。


根據TCP協議定義的3次握手斷開連接規定,發起socket主動關閉的一方 socket將進入TIME_WAIT狀態,TIME_WAIT狀態將持續2個MSL(Max Segment Lifetime),在Windows下默認為4分鐘,即240秒,TIME_WAIT狀態下的socket不能被回收使用. 具體現象是對於一個處理大量短連接的服務器,如果是由服務器主動關閉客戶端的連接,將導致服務器端存在大量的處於TIME_WAIT狀態的socket, 甚至比處於Established狀態下的socket多的多,嚴重影響服務器的處理能力,甚至耗盡可用的socket,停止服務. TIME_WAIT是TCP協議用以保證被重新分配的socket不會受到之前殘留的延遲重發報文影響的機制,是必要的邏輯保證.


TCP協議中有TIME_WAIT這個狀態
主要有兩個原因
1。防止上一次連接中的包,迷路後重新出現,影響新連接(經過2MSL,上一次連接中所有的重復包都會消失)
2。可靠的關閉TCP連接。在主動關閉方發送的最後一個 ack(fin) ,有可能丟失,這時被動方會重新發
fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。


查看系統TCP連接資源命令


查看網絡連接數:

# netstat -an |grep xx |wc -l        查看某個/特定ip的連接數
# netstat -an |grep TIME_WAIT|wc -l    查看連接數等待time_wait狀態連接數
# netstat -an |grep ESTABLISHED |wc -l    查看建立穩定連接數量

查看不同狀態的連接數數量

# 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

一般情況下,系統的socket資源默認5000個。(非官方)


查看每個ip跟服務器建立的連接數

# netstat -nat|grep "tcp"|awk ‘ {print$5}‘|awk -F : ‘{print$1}‘|sort|uniq -c|sort -rn
    444 10.71.177.123
    102 100.11.71.123
    101 49.14.55.132
(PS:正則解析:顯示第5列,-F : 以:分割,顯示列,sort 排序,uniq -c統計排序過程中的重復行,sort -rn 按純數字進行逆序排序)

查看每個ip建立的ESTABLISHED/TIME_OUT狀態的連接數

# 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

通過調整內核參數:

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 = 30
#然後執行 /sbin/sysctl -p 讓參數生效。

配置說明:

net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防範少量SYN攻擊,默認為0,表示關閉;

net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉;

net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉;

net.ipv4.tcp_fin_timeout=30修改系統默認的 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套接字拖死。

調優完畢,再壓一下看看效果吧。

# netstat -an | awk ‘/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}‘


問題2:怎麽解決請求結束後依然存在大量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)


本文出自 “奔跑在路上” 博客,謝絕轉載!

Tcp連接出現大量ESTABLISHED連接解決方法