在平常運(yùn)維服務(wù)器的時(shí)候,需要查看各種連接狀態(tài),所以必須要對(duì)TCP連接狀態(tài)非常熟悉才知道每個(gè)狀態(tài)的意義;只有知道了這些參數(shù)的意義才可以相對(duì)應(yīng)的優(yōu)化。
瀘縣網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站開(kāi)發(fā)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)從2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專(zhuān)注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
查看狀態(tài)命令:
[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
各個(gè)狀態(tài)的意義如下 :
LISTEN:表示監(jiān)聽(tīng)的TCP端口已經(jīng)打開(kāi);?
SYN_SENT:客戶(hù)端在發(fā)送建立連接(SYN)請(qǐng)求后的狀態(tài);?
SYN_RECV:服務(wù)端在收到SYN請(qǐng)求建立連接后,發(fā)送SYN+ACK后的狀態(tài);?
ESTABLISHED:客戶(hù)端在發(fā)送完ACK后的狀態(tài)、服務(wù)端在收到ACK后的狀態(tài),此時(shí)連接正式建立;?
FIN_WAIT1:客戶(hù)端發(fā)送完FIN后的狀態(tài);
CLOSE_WAIT:服務(wù)端收到客戶(hù)端的FIN請(qǐng)求后,發(fā)送對(duì)FIN的ACK后的狀態(tài);?
FIN_WAIT2:收到服務(wù)端發(fā)送的對(duì)之前FIN的ACK后的狀態(tài);?
LAST_ACK:服務(wù)端處理完最后的數(shù)據(jù),發(fā)送FIN后的狀態(tài);
TIME_WAIT:收到服務(wù)端發(fā)送的FIN后的狀態(tài),表示處于空閑等待階段;?
CLOSED:TIME_WAIT時(shí)間到達(dá)后,發(fā)送對(duì)FIN的確認(rèn)ACK后的狀態(tài),發(fā)送完ACK表示連接已關(guān)閉 ;
CLOSING:連接雙方同時(shí)發(fā)送關(guān)閉請(qǐng)求和確認(rèn)時(shí)的狀態(tài);?
三次握手四次斷開(kāi)流程示意:
????
更直觀的流程示意:
????
關(guān)于四次斷開(kāi):
?? a.先由客戶(hù)端向服務(wù)器端發(fā)送一個(gè)FIN,請(qǐng)求關(guān)閉數(shù)據(jù)傳輸。
?? b.當(dāng)服務(wù)器接收到客戶(hù)端的FIN時(shí),向客戶(hù)端發(fā)送一個(gè)ACK,其中ack的值等于FIN+SEQ
?? c.然后服務(wù)器向客戶(hù)端發(fā)送一個(gè)FIN,告訴客戶(hù)端應(yīng)用程序關(guān)閉。
?? d.當(dāng)客戶(hù)端收到服務(wù)器端的FIN是,回復(fù)一個(gè)ACK給服務(wù)器端。其中ack的值等于FIN+SEQ
為什么要4次才能斷開(kāi)?
?? a.確保數(shù)據(jù)能夠完成傳輸。
?? b.但關(guān)閉連接時(shí),當(dāng)收到對(duì)方的FIN報(bào)文通知時(shí),它僅僅表示對(duì)方?jīng)]有數(shù)據(jù)發(fā)送給你了;
?? c.但未必你所有的數(shù)據(jù)都全部發(fā)送給對(duì)方了,所以你可以未必會(huì)馬上會(huì)關(guān)閉SOCKET,也即你可能還需要發(fā)送一些數(shù)據(jù)給對(duì)方之后
?? d.再發(fā)送FIN報(bào)文給對(duì)方來(lái)表示你同意現(xiàn)在可以關(guān)閉連接了,所以它這里的ACK報(bào)文和FIN報(bào)文多數(shù)情況下都是分開(kāi)發(fā)送的。 ?? ???
下面看下大家一般比較關(guān)心的三種TCP狀態(tài):
????SYN_RECV:
????服務(wù)端收到建立連接的SYN沒(méi)有收到ACK包的時(shí)候處在SYN_RECV狀態(tài)。有兩個(gè)相關(guān)系統(tǒng)配置:
????1. net.ipv4.tcp_synack_retries? --> 默認(rèn)值是5
????????
?????? 對(duì)于遠(yuǎn)端的連接請(qǐng)求SYN,內(nèi)核會(huì)發(fā)送SYN + ACK數(shù)據(jù)報(bào),以確認(rèn)收到上一個(gè) SYN連接請(qǐng)求包。這是所謂的三次握手( threeway handshake)機(jī)制的第二個(gè)步驟。這里決定內(nèi)核在放棄連接之前所送出的 SYN+ACK 數(shù)目。不應(yīng)該大于255,默認(rèn)值是5,對(duì)應(yīng)于180秒左右時(shí)間。通常我們不對(duì)這個(gè)值進(jìn)行修改,因?yàn)槲覀兿M鸗CP連接不要因?yàn)榕紶柕膩G包而無(wú)法建立。
????2. net.ipv4.tcp_syncookies --> 默認(rèn)值是1
??????
???? 一般服務(wù)器都會(huì)設(shè)置net.ipv4.tcp_syncookies=1來(lái)防止SYN Flood***。假設(shè)一個(gè)用戶(hù)向服務(wù)器發(fā)送了SYN報(bào)文后突然死機(jī)或掉線(xiàn),那么服務(wù)器在發(fā)出SYN+ACK應(yīng)答報(bào)文后是無(wú)法收到客戶(hù)端的ACK報(bào)文的(第三次握手無(wú)法完成),這種情況下服務(wù)器端一般會(huì)重試(再次發(fā)送SYN+ACK給客戶(hù)端)并等待一段時(shí)間后丟棄這個(gè)未完成的連接,這段時(shí)間的長(zhǎng)度我們稱(chēng)為SYN Timeout,一般來(lái)說(shuō)這個(gè)時(shí)間是分鐘的數(shù)量級(jí)(大約為30秒-2分鐘)。
??? 這些處在SYNC_RECV的TCP連接稱(chēng)為半連接,并存儲(chǔ)在內(nèi)核的半連接隊(duì)列中,在內(nèi)核收到對(duì)端發(fā)送的ack包時(shí)會(huì)查找半連接隊(duì)列,并將符合的requst_sock信息存儲(chǔ)到完成三次握手的連接的隊(duì)列中,然后刪除此半連接。大量SYNC_RECV的TCP連接會(huì)導(dǎo)致半連接隊(duì)列溢出,這樣后續(xù)的連接建立請(qǐng)求會(huì)被內(nèi)核直接丟棄,這就是SYN Flood***。
??? 能夠有效防范SYN Flood***的手段之一,就是SYN Cookie。SYN Cookie原理由D. J. Bernstain和 Eric Schenk發(fā)明。SYN Cookie是對(duì)TCP服務(wù)器端的三次握手協(xié)議作一些修改,專(zhuān)門(mén)用來(lái)防范SYN Flood***的一種手段。它的原理是,在TCP服務(wù)器收到TCP SYN包并返回TCP SYN+ACK包時(shí),不分配一個(gè)專(zhuān)門(mén)的數(shù)據(jù)區(qū),而是根據(jù)這個(gè)SYN包計(jì)算出一個(gè)cookie值。在收到TCP ACK包時(shí),TCP服務(wù)器在根據(jù)那個(gè)cookie值檢查這個(gè)TCP ACK包的合法性。如果合法,再分配專(zhuān)門(mén)的數(shù)據(jù)區(qū)進(jìn)行處理未來(lái)的TCP連接。
??? 觀測(cè)服務(wù)上SYN_RECV連接個(gè)數(shù)為:7314,對(duì)于一個(gè)高并發(fā)的服務(wù)器,這個(gè)數(shù)字比較正常。
????CLOSE_WAIT
????發(fā)起TCP連接關(guān)閉的一方稱(chēng)為client,被動(dòng)關(guān)閉的一方稱(chēng)為server。被動(dòng)關(guān)閉的server收到FIN后,但未發(fā)出ACK的TCP狀態(tài)是CLOSE_WAIT。出現(xiàn)這種狀況一般都是由于server端代碼的問(wèn)題,如果你的服務(wù)器上出現(xiàn)大量CLOSE_WAIT,應(yīng)該要考慮檢查代碼。
????TIME_WAIT
????根據(jù)TCP協(xié)議定義的3次握手?jǐn)嚅_(kāi)連接規(guī)定,發(fā)起socket主動(dòng)關(guān)閉的一方 socket將進(jìn)入TIME_WAIT狀態(tài)。TIME_WAIT狀態(tài)將持續(xù)2個(gè)MSL(Max Segment Lifetime),在Windows下默認(rèn)為4分鐘,即240秒。TIME_WAIT狀態(tài)下的socket不能被回收使用. 具體現(xiàn)象是對(duì)于一個(gè)處理大量短連接的服務(wù)器,如果是由服務(wù)器主動(dòng)關(guān)閉客戶(hù)端的連接,將導(dǎo)致服務(wù)器端存在大量的處于TIME_WAIT狀態(tài)的socket, 甚至比處于Established狀態(tài)下的socket多的多,嚴(yán)重影響服務(wù)器的處理能力,甚至耗盡可用的socket,停止服務(wù)。
????為什么需要TIME_WAIT?TIME_WAIT是TCP協(xié)議用以保證被重新分配的socket不會(huì)受到之前殘留的延遲重發(fā)報(bào)文影響的機(jī)制,是必要的邏輯保證。
????和TIME_WAIT狀態(tài)有關(guān)的系統(tǒng)參數(shù)有一般由3個(gè),本廠設(shè)置如下:
????net.ipv4.tcp_tw_recycle = 1
????net.ipv4.tcp_tw_reuse = 1
????net.ipv4.tcp_fin_timeout = 30
????net.ipv4.tcp_fin_timeout,默認(rèn)60s,減少這個(gè)數(shù)值以便加快系統(tǒng)關(guān)閉處于 FIN_WAIT2 狀態(tài)的 TCP 連接,建議值為30。
????net.ipv4.tcp_tw_reuse = 1表示開(kāi)啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認(rèn)為0,表示關(guān)閉;
????net.ipv4.tcp_tw_recycle = 1表示開(kāi)啟TCP連接中TIME-WAIT sockets的快速回收,默認(rèn)為0,表示關(guān)閉。
???