1、在解決這個問題之前,需要了解什麼是tcp連線數?
大家很明白tcp
初始化連線三次握手吧:發
syn包,然後返回
syn/ack
包,再發
ack包,連線正式建立。但是這裡有點出入
/ack
包,當請求者收到
syn
後,就開始建立連線了。
而被請求者第三次握手結束後才建立連線。
但是大家明白關閉連線的工作原理嗎?關閉連線要四次握手:發fin包,a
ck 包,
fin包,
ack包,四次握手!!為什麼呢,因為
tcp連線是全雙工,
我關了你的連線,並不等於你關了我的連線。
當應用層向tcp層傳送用於網間傳輸的、用8位位元組表示的資料流,tcp則把資料流分割成適當長度的報文段,最大傳輸段大小(mss)通常受該計算機連線的網路的資料鏈路層的最大傳送單元(mtu)限制。之後tcp把資料報傳給ip層,由它來通過網路將包傳送給接收端實體的tcp層。
tcp為了保證報文傳輸的可靠
[1],就給每個包乙個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的位元組發回乙個相應的確認(ack);如果傳送端實體在合理的往返時延(rtt)內未收到確認,那麼對應的資料(假設丟失了)將會被重傳。
在擁塞控制上,採用廣受好評的tcp擁塞控制演算法(也稱aimd演算法)。該演算法主要包括三個主要部分:1)加性增、乘性減;2)慢啟動;3)對超時事件做出反應。
檢視當前連線有多少time_wait數命令?
#netstat -n | awk '/^tcp/ end '
last_ack 14 (代表等待所有分組死掉的連線狀態的數量)
syn_recv 348 (代表乙個連線請求已經到達,等待確認的連線狀態的數量)
established 70 (代表正常資料傳輸狀態的連線狀態的數量)
fin_wait1 229 (代表應用說它已經完成的連線狀態的數量)
fin_wait2 30 (代表另一邊已同意釋放的連線狀態的數量)
closing 33 (代表兩邊同時嘗試關閉的連線狀態的數量)
time_wait 18122 (表示收到了對方的fin報文,並傳送出了ack報文,就等2msl後即可回到closed可用狀態了。如果fin_wait_1狀態下,收到了對方同時帶fin標誌和ack標誌的報文時,可以直接進入到time_wait狀態,而無須經過fin_wait_2狀態)
closed
無連線是活動的或正在進行
listen
伺服器在等待進入呼叫
syn_sent
應用已經開始,開啟乙個連線
下面解釋一下為啥要這樣寫:
乙個簡單的管道符連線了netstat和awk命令。
——————————————————————
先來看看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製表符分割,美化一下。
檢視當前系統下所有連線狀態的數:
[root@vps ~]#netstat -n|awk '/^tcp/end'如發現系統存在大量time_wait狀態的連線,通過調整核心引數解決:time_wait 286
fin_wait1 5
fin_wait2 6
established 269
syn_recv 5
closing 1
編輯檔案/etc/sysctl.conf,加入以下內容:
net.ipv4.tcp_syncookies = 1然後執行 /sbin/sysctl -p 讓引數生效。net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
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
修改系預設的 timeout 時間
其它引數說明:
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。對於apache、nginx等伺服器,上幾行的引數可以很好地減少time_wait套接字數量,但是對於squid,效果卻不大。此項引數可以控制time_wait套接字的最大數量,避免squid伺服器被大量的time_wait套接字拖死。
是不是所有執行主動關閉的socket都會進入time_wait狀態呢?
有沒有什麼情況使主動關閉的socket直接進入closed狀態呢?
主動關閉的一方在傳送最後乙個 ack 後
就會進入 time_wait 狀態 停留2msl(max segment lifetime)時間
這個是tcp/ip必不可少的,也就是「解決」不了的。
也就是tcp/ip設計者本來是這麼設計的
主要有兩個原因
1。防止上一次連線中的包,迷路後重新出現,影響新連線
(經過2msl,上一次連線中所有的重複包都會消失)
2。可靠的關閉tcp連線
在主動關閉方傳送的最後乙個 ack(fin) ,有可能丟失,這時被動方會重新發
fin, 如果這時主動方處於 closed 狀態 ,就會響應 rst 而不是 ack。所以
主動方要處於 time_wait 狀態,而不能是 closed 。
time_wait 並不會占用很大資源的,除非受到攻擊。
還有,如果一方 send 或 recv 超時,就會直接進入 closed 狀態
注:以上內容為查閱相關資料整理所得
TCP連線中TIME WAIT連線過多
原文 主題tcp ip socket timewait並不是多餘的 在tcp協議被創造,經歷了大量的實際場景實踐之後 timewait 出現了,因為tcp主 動關閉連線的一方需要timewait狀態,它是我們的朋友。這是 unix網路程式設計 的作者 steven對timewait的態度。tcp要保...
tcp連線中TIME WAIT狀態過多
參考自 作用 1.保證雙方正常種植資料流傳輸 最後乙個 ack丟失了,被動關閉一方會重發它的 fin,主動關閉一方必須維持乙個有效狀態資訊 timewait狀態下維持 以便能夠重發 ack,否則被動一方會認為有錯誤產生 2.保證 在下乙個人使用的ip位址與埠與先前的完全相同的情況下,上乙個殘留的資料...
TIME WAIT狀態過多的排查
一 現象 伺服器有兩個現象,第一是tcp連線數不多,不超過10個,但是time wait狀態的2000。第二個按照以往的性質,在很少使用者訪問的情況下,伺服器的資源幾乎沒有使用,比如cpu,不超過5 現在沒有什麼使用者的的情況下,cpu損耗堅持在40 左右,夜間也不停歇。裡面執行著好幾個web專案,...