您好,登錄后才能下訂單哦!
在平常運維服務器的時候,需要查看各種連接狀態,所以必須要對TCP連接狀態非常熟悉才知道每個狀態的意義;只有知道了這些參數的意義才可以相對應的優化。
查看狀態命令:
[root@tomcat10?logs]#?netstat?-na?|?awk?'/^tcp/{s[$6]++}END{for(key?in?s)?print?key,s[key]}' TIME_WAIT?1443 CLOSE_WAIT?1122 SYN_SENT?3 FIN_WAIT1?2074 FIN_WAIT2?195 ESTABLISHED?89782 SYN_RECV?7314 LISTEN?9 CLOSING?9 LAST_ACK?2372
各個狀態的意義如下 :
LISTEN:表示監聽的TCP端口已經打開;?
SYN_SENT:客戶端在發送建立連接(SYN)請求后的狀態;?
SYN_RECV:服務端在收到SYN請求建立連接后,發送SYN+ACK后的狀態;?
ESTABLISHED:客戶端在發送完ACK后的狀態、服務端在收到ACK后的狀態,此時連接正式建立;?
FIN_WAIT1:客戶端發送完FIN后的狀態;
CLOSE_WAIT:服務端收到客戶端的FIN請求后,發送對FIN的ACK后的狀態;?
FIN_WAIT2:收到服務端發送的對之前FIN的ACK后的狀態;?
LAST_ACK:服務端處理完最后的數據,發送FIN后的狀態;
TIME_WAIT:收到服務端發送的FIN后的狀態,表示處于空閑等待階段;?
CLOSED:TIME_WAIT時間到達后,發送對FIN的確認ACK后的狀態,發送完ACK表示連接已關閉 ;
CLOSING:連接雙方同時發送關閉請求和確認時的狀態;?
三次握手四次斷開流程示意:
????
更直觀的流程示意:
????
關于四次斷開:
?? a.先由客戶端向服務器端發送一個FIN,請求關閉數據傳輸。
?? b.當服務器接收到客戶端的FIN時,向客戶端發送一個ACK,其中ack的值等于FIN+SEQ
?? c.然后服務器向客戶端發送一個FIN,告訴客戶端應用程序關閉。
?? d.當客戶端收到服務器端的FIN是,回復一個ACK給服務器端。其中ack的值等于FIN+SEQ
為什么要4次才能斷開?
?? a.確保數據能夠完成傳輸。
?? b.但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;
?? c.但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之后
?? d.再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這里的ACK報文和FIN報文多數情況下都是分開發送的。 ?? ???
下面看下大家一般比較關心的三種TCP狀態:
????SYN_RECV:
????服務端收到建立連接的SYN沒有收到ACK包的時候處在SYN_RECV狀態。有兩個相關系統配置:
????1. net.ipv4.tcp_synack_retries? --> 默認值是5
????????
?????? 對于遠端的連接請求SYN,內核會發送SYN + ACK數據報,以確認收到上一個 SYN連接請求包。這是所謂的三次握手( threeway handshake)機制的第二個步驟。這里決定內核在放棄連接之前所送出的 SYN+ACK 數目。不應該大于255,默認值是5,對應于180秒左右時間。通常我們不對這個值進行修改,因為我們希望TCP連接不要因為偶爾的丟包而無法建立。
????2. net.ipv4.tcp_syncookies --> 默認值是1
??????
???? 一般服務器都會設置net.ipv4.tcp_syncookies=1來防止SYN Flood***。假設一個用戶向服務器發送了SYN報文后突然死機或掉線,那么服務器在發出SYN+ACK應答報文后是無法收到客戶端的ACK報文的(第三次握手無法完成),這種情況下服務器端一般會重試(再次發送SYN+ACK給客戶端)并等待一段時間后丟棄這個未完成的連接,這段時間的長度我們稱為SYN Timeout,一般來說這個時間是分鐘的數量級(大約為30秒-2分鐘)。
??? 這些處在SYNC_RECV的TCP連接稱為半連接,并存儲在內核的半連接隊列中,在內核收到對端發送的ack包時會查找半連接隊列,并將符合的requst_sock信息存儲到完成三次握手的連接的隊列中,然后刪除此半連接。大量SYNC_RECV的TCP連接會導致半連接隊列溢出,這樣后續的連接建立請求會被內核直接丟棄,這就是SYN Flood***。
??? 能夠有效防范SYN Flood***的手段之一,就是SYN Cookie。SYN Cookie原理由D. J. Bernstain和 Eric Schenk發明。SYN Cookie是對TCP服務器端的三次握手協議作一些修改,專門用來防范SYN Flood***的一種手段。它的原理是,在TCP服務器收到TCP SYN包并返回TCP SYN+ACK包時,不分配一個專門的數據區,而是根據這個SYN包計算出一個cookie值。在收到TCP ACK包時,TCP服務器在根據那個cookie值檢查這個TCP ACK包的合法性。如果合法,再分配專門的數據區進行處理未來的TCP連接。
??? 觀測服務上SYN_RECV連接個數為:7314,對于一個高并發的服務器,這個數字比較正常。
????CLOSE_WAIT
????發起TCP連接關閉的一方稱為client,被動關閉的一方稱為server。被動關閉的server收到FIN后,但未發出ACK的TCP狀態是CLOSE_WAIT。出現這種狀況一般都是由于server端代碼的問題,如果你的服務器上出現大量CLOSE_WAIT,應該要考慮檢查代碼。
????TIME_WAIT
????根據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?TIME_WAIT是TCP協議用以保證被重新分配的socket不會受到之前殘留的延遲重發報文影響的機制,是必要的邏輯保證。
????和TIME_WAIT狀態有關的系統參數有一般由3個,本廠設置如下:
????net.ipv4.tcp_tw_recycle = 1
????net.ipv4.tcp_tw_reuse = 1
????net.ipv4.tcp_fin_timeout = 30
????net.ipv4.tcp_fin_timeout,默認60s,減少這個數值以便加快系統關閉處于 FIN_WAIT2 狀態的 TCP 連接,建議值為30。
????net.ipv4.tcp_tw_reuse = 1表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認為0,表示關閉;
????net.ipv4.tcp_tw_recycle = 1表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。
???
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。