1. 程式人生 > >TCP連接中time_wait在開發中的影響-搜人以魚不如授之以漁

TCP連接中time_wait在開發中的影響-搜人以魚不如授之以漁

清除 color title 打印 出現 .com ace tor width

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

netstat -an|awk ‘/tcp/ {print $6}‘|sort|uniq -c
     16 CLOSING
    130 ESTABLISHED
    298 FIN_WAIT1
     13 FIN_WAIT2
      9 LAST_ACK
      7 LISTEN
    103 SYN_RECV
   5204 TIME_WAIT

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

原文和作者一起討論:http://www.cnblogs.com/intsmaze/p/7076624.html

微信:intsmaze

技術分享

netstat -ae |grep mysql
tcp        0      0 aaaa:53045               192.168.12.13:mysql           TIME_WAIT   root       0
tcp        0      0 aaaa:53044               192.168.12.13:mysql           TIME_WAIT   root       0
tcp        0      0 aaaa:53051               192.168.12.13:mysql           TIME_WAIT   root       0
tcp        0      0 aaaa:53050               192.168.12.13:mysql           TIME_WAIT   root       0
tcp        0      0 aaaa:53049               192.168.12.13:mysql           TIME_WAIT   root       0

發現系統存在大量TIME_WAIT狀態的連接,通過調整內核參數解決,

vi /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
net.ipv4.tcp_keepalive_time = 1200    
net.ipv4.ip_local_port_range = 1024    65000   ## 端口分配範圍
net.ipv4.tcp_max_tw_buckets = 5000   ## 設置"time_wait"的桶最多容納5000個
然後執行 /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  表示如果套接字由本端要求關閉,這個參數決定了他在保持FIN-WAIT-2狀態的時間。
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。
[阿裏巴巴java開發手冊推薦]高並發服務器建議調小 TCP 協議的 time_wait 超時時間。 說明: 操作系統默認 240 秒後,才會關閉處於 time_wait 狀態的連接,在高並發訪問下,服務器端會因為處於 time_wait 的連接數太多,可能無法建立新的連接,所以需要在服務器上調小此等待值。 正例: 在 linux 服務器上請通過變更/etc/sysctl.conf 文件去修改該缺省值(秒) : net.ipv4.tcp_fin_timeout = 30。

搜人以魚不如授之以漁,讓我們來回顧計算機網絡中TCP協議的部分詳解,摘自-謝希仁 計算機網絡

TCP 的運輸連接的三個階段
運輸連接就有三個階段,即:連接建立、數據傳送和連接釋放。運輸連接的管理就是使運輸連接的建立和釋放都能正常地進行。
連接建立過程中要解決以下三個問題:
要使每一方能夠確知對方的存在。
要允許雙方協商一些參數(如最大報文段長度,最大窗口大小,服務質量等)。
能夠對運輸實體資源(如緩存大小,連接表中的項目等)進行分配。
客戶-服務器方式
TCP 連接的建立都是采用客戶服務器方式。
主動發起連接建立的應用進程叫做客戶(client)。
被動等待連接建立的應用進程叫做服務器(server)。
TCP 的連接建立

技術分享

A 的 TCP 向 B 發出連接請求報文段,其首部中的同步位 SYN = 1,並選擇序號 seq = x,表明傳送數據時的第一個數據字節的序號是 x。
B 的 TCP 收到連接請求報文段後,如同意,則發回確認。
B 在確認報文段中應使 SYN = 1,使 ACK = 1,其確認號ack = x + 1,自己選擇的序號 seq = y。

技術分享

A 收到此報文段後向 B 給出確認,其 ACK = 1,確認號 ack = y + 1。
A 的 TCP 通知上層應用進程,連接已經建立。

B 的 TCP 收到主機 A 的確認後,也通知其上層應用進程:TCP 連接已經建立。

用三次握手建立 TCP 連接的各狀態

技術分享

TCP 的連接釋放

技術分享

數據傳輸結束後,通信的雙方都可釋放連接
現在 A 的應用進程先向其 TCP 發出連接釋放報文段,並停止再發送數據,主動關閉 TCP 連接。A 把連接釋放報文段首部的 FIN = 1,其序號 seq = u,等待 B 的確認。

技術分享

B 發出確認,確認號 ack = u + 1,而這個報文段自己的序號 seq = v。

TCP 服務器進程通知高層應用進程。從 A 到 B 這個方向的連接就釋放了,TCP 連接處於半關閉狀態。B 若發送數據,A 仍要接收。
若 B 已經沒有要向 A 發送的數據,其應用進程就通知 TCP 釋放連接。A 收到連接釋放報文段後,必須發出確認。在確認報文段中 ACK = 1,確認號 ack = w + 1,自己的序號 seq = u + 1。

TCP 連接必須經過時間 2MSL 後才真正釋放掉。

技術分享

第一,為了保證 A 發送的最後一個 ACK 報文段能夠到達 B。
第二,防止 “已失效的連接請求報文段”出現在本連接中。A 在發送完最後一個 ACK 報文段後,再經過時間 2MSL,就可以使本連接持續的時間內所產生的所有報文段,都從網絡中消失。這樣就可以使下一個新的連接中不會出現這種舊的連接請求報文段。
            老鐵快->關註,點贊,轉發

TCP連接中time_wait在開發中的影響-搜人以魚不如授之以漁