根據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。
搜人以魚不如授之以漁,讓我們來回顧計算機網絡中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,就可以使本連接持續的時間內所產生的所有報文段,都從網絡中消失。這樣就可以使下一個新的連接中不會出現這種舊的連接請求報文段。
老鐵快->關注,點贊,轉發