web服務減少服務器TIME_WAIT

TIME_WAIT狀態的意義:

         客戶端與服務器端建立TCP/IP連接後關閉SOCKET後,服務器端連接的端口狀態爲TIME_WAIT,是不是所有執行主動關閉的socket都會進入TIME_WAIT狀態呢?有沒有什麼情況使主動關閉的socket直接進入CLOSED狀態呢?

         主動關閉的一方在發送最後一個 ack 後就會進入 TIME_WAIT 狀態 停留2MSLmax segment lifetime)時間這個是TCP/IP必不可少的,也就是解決不了的。也就是TCP/IP設計者本來是這麼設計的主要有兩個原因:
         1、防止上一次連接中的包,迷路後重新出現,影響新連接(經過2MSL,上一次連接中所有的重複包都會消失)
         2、可靠的關閉TCP連接在主動關閉方發送的最後一個 ack(fin) ,有可能丟失,這時被動方會重新發fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。TIME_WAIT 並不會佔用很大資源的,除非受到***。在Squid服務器中可輸入如下命令:

主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED TIME_WAIT 並不會佔用很大資源的,除非受到***。在Squid服務器中可輸入如下命令:

  1. #netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 
  2. LAST_ACK 14 
  3. SYN_RECV 348 
  4. ESTABLISHED 70 
  5. FIN_WAIT1 229 
  6. FIN_WAIT2 30 
  7. CLOSING 33 
  8. TIME_WAIT 18122 

 

狀態描述:
CLOSED
:無連接是活動的或正在進行
LISTEN
:服務器在等待進入呼叫
SYN_RECV
:一個連接請求已經到達,等待確認
SYN_SENT
:應用已經開始,打開一個連接
ESTABLISHED
:正常數據傳輸狀態
FIN_WAIT1
:應用說它已經完成
FIN_WAIT2
:另一邊已同意釋放
ITMED_WAIT
:等待所有分組死掉
CLOSING
:兩邊同時嘗試關閉
TIME_WAIT
:另一邊已初始化一個釋放
LAST_ACK
:等待所有分組死掉

也就是說,這條命令可以把當前系統的網絡連接狀態分類彙總。

下面解釋一下爲啥要這樣寫:

一個簡單的管道符連接了netstatawk命令。

——————————————————————

先來看看netstat

netstat -n

Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 123.123.123.123:80 234.234.234.234:12345 TIME_WAIT

你實際執行這條命令的時候,可能會得到成千上萬條類似上面的記錄,不過我們就拿其中的一條就足夠了。

——————————————————————

再來看看awk

/^tcp/
濾出tcp開頭的記錄,屏蔽udp, socket等無關記錄。

state[]
相當於定義了一個名叫state的數組

NF
表示記錄的字段數,如上所示的記錄,NF等於6

$NF
表示某個字段的值,如上所示的記錄,$NF也就是$6,表示第6個字段的值,也就是TIME_WAIT

state[$NF]
表示數組元素的值,如上所示的記錄,就是state[TIME_WAIT]狀態的連接數

++state[$NF]
表示把某個數加一,如上所示的記錄,就是把state[TIME_WAIT]狀態的連接數加一

END
表示在最後階段要執行的命令

for(key in state)
遍歷數組

print key,”\t”,state[key]
打印數組的鍵和值,中間用\t製表符分割,美化一下。

如發現系統存在大量TIME_WAIT狀態的連接,通過調整內核參數解決,
vim /etc/sysctl.conf
編輯文件,加入以下內容:

  1. net.ipv4.tcp_syncookies = 1 
  2. net.ipv4.tcp_tw_reuse = 1 
  3. net.ipv4.tcp_tw_recycle = 1 
  4. net.ipv4.tcp_fin_timeout = 30 


然後執行 /sbin/sysctl -p 讓參數生效。

Linux下高併發的Squid服務器,TCP TIME_WAIT套接字數量經常達到兩、三萬,服務器很容易被拖死。通過修改Linux內核參數,可以減少Squid服務器的TIME_WAIT套接字數量。
  vi /etc/sysctl.conf

  增加以下幾行:引用

 

  1. net.ipv4.tcp_fin_timeout = 30 
  2. net.ipv4.tcp_keepalive_time = 1200 
  3. net.ipv4.tcp_syncookies = 1 
  4. net.ipv4.tcp_tw_reuse = 1 
  5. net.ipv4.tcp_tw_recycle = 1 
  6. net.ipv4.ip_local_port_range = 1024 65000 
  7. net.ipv4.tcp_max_syn_backlog = 8192 
  8. net.ipv4.tcp_max_tw_buckets = 5000 


  說明:
  

  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 = 30 表示如果套接字由本端要求關閉,這個參數決定了它保持在FIN-WAIT-2狀態的時間。 
  5.   net.ipv4.tcp_keepalive_time = 1200 表示當keepalive起用的時候,TCP發送keepalive消息的頻度。缺省是2小時,改爲20分鐘。 
  6.   net.ipv4.ip_local_port_range = 1024 65000 表示用於向外連接的端口範圍。缺省情況下很小:32768到61000,改爲1024到65000。 
  7.   net.ipv4.tcp_max_syn_backlog = 8192 表示SYN隊列的長度,默認爲1024,加大隊列長度爲8192,可以容納更多等待連接的網絡連接數。 
  8.    net.ipv4.tcp_max_tw_buckets = 5000表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並打印警告信息。默認爲 180000,改爲5000。對於Apache、Nginx等服務器,上幾行的參數可以很好地減少TIME_WAIT套接字數量,但是對於Squid,效 果卻不大。此項參數可以控制TIME_WAIT套接字的最大數量,避免Squid服務器被大量的TIME_WAIT套接字拖死。 


  執行以下命令使配置生效:
/sbin/sysctl -p

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