雜談 TIME_WAIT 狀態(tài)

在談time_wait狀態(tài)前廊驼,我們來看下Tcp的四次揮手吧:

01.01.FIN_ACK..png

簡單解釋一下這張網(wǎng)圖吧:

  • 客戶端傳完數(shù)據(jù)据过,想拔*無情,此時就會發(fā)送TCP首部FIN標志位置為1的報文妒挎,跟服務(wù)端說我完事了绳锅。之后客戶端進入了 FIN_WAIT_1 狀態(tài)。
  • 此時服務(wù)端收到報文后酝掩,發(fā)送確認報文 ACK,表示老娘知道你一滴都沒有了鳞芙,那我也就準備收拾收拾結(jié)束了。進入了 CLOSE_WAIT 狀態(tài)期虾。 表示等著進程調(diào)用close 函數(shù)關(guān)閉連接原朝。
  • 客戶端收到了 ACK 之后,狀態(tài)就從 FIN_WAIT1 變成了 FIN_WAIT2〕瓜現(xiàn)在客戶端的發(fā)送通道就關(guān)了竿拆。但是此時還可以接收數(shù)據(jù)。
  • 當服務(wù)端進入 CLOSE_WAIT 之后宾尚,他還會繼續(xù)處理數(shù)據(jù)丙笋,等到等到進程的 read 函數(shù)返回 0 后,就會調(diào)用 closLAST_ACKe 函數(shù)煌贴,開始發(fā)送 FIN 報文御板,進入LAST_ACK 狀態(tài)
  • 客戶端收到FIN報文后,會回復(fù) ACK 報文給服務(wù)端牛郑,然后終于到了 TIME_WAIT 狀態(tài)(等死我了)怠肋。在 Linux 系統(tǒng)下大約等待 1 分鐘后,TIME_WAIT 狀態(tài)的連接才會徹底關(guān)閉淹朋。
  • 當服務(wù)端收到最后的ACK之后笙各,兩邊就關(guān)啦。(光燈睡覺)

這時候你會發(fā)現(xiàn)一件事情:主動關(guān)閉連接的础芍,才有 TIME_WAIT 狀態(tài)杈抢。

是的,沒錯仑性,你真棒惶楼!

為什么要有TIME_WAIT呢?

TIME_WAIT 是主動方四次揮手的最后一個狀態(tài),也是最常遇見的狀態(tài)歼捐。

  1. 保證連接正確關(guān)閉

TIME-WAIT 一個作用是等待足夠的時間以確保最后的 ACK 能讓被動關(guān)閉方接收何陆,從而幫助其正常關(guān)閉。

明明客戶端發(fā)完最后的ACK了豹储,我客戶端憑啥還要等按ぁ?哦吼剥扣,這不就暴露問題了嗎晃洒?客戶端發(fā)了ACK,服務(wù)端沒收到怎么辦朦乏?那就再發(fā)個FIN給客戶端球及。這時候就會重傳tcp_orphan_retries 次,這時候沒有TIME_WAIT豈不是很尬呻疹?你客戶端連接收通道都關(guān)了我服務(wù)端傳給誰俺砸?刽锤?镊尺?那服務(wù)端還關(guān)不關(guān)了?就一直卡在了LASTACK狀態(tài)了并思。

  1. 防止舊連接的數(shù)據(jù)包

TIME-WAIT 還有一個作用是防止收到歷史數(shù)據(jù)庐氮,從而導致數(shù)據(jù)錯亂的問題。

試想一個場景沒有 TIME_WAIT我直接關(guān)了宋彼,在關(guān)閉之前服務(wù)端一個報文因為網(wǎng)絡(luò)原因延遲了弄砍,到達的時候這個接口被重新握手啟動了。
新的客戶端收到了延遲的數(shù)據(jù)包输涕,那就尷尬了音婶。

所以,TCP 就設(shè)計出了這么一個機制莱坎,經(jīng)過 2MSL 這個時間衣式,足以讓兩個方向上的數(shù)據(jù)包都被丟棄,
使得原來連接的數(shù)據(jù)包在網(wǎng)絡(luò)中都自然消失檐什,再出現(xiàn)的數(shù)據(jù)包一定都是新建立連接所產(chǎn)生的碴卧。

為什么TIME_WAIT是2MSL呢?

之前有提到一手:在 Linux 系統(tǒng)下大約等待 1 分鐘后,TIME_WAIT 狀態(tài)的連接才會徹底關(guān)閉乃正。

那么為什么 TIME_WAIT 狀態(tài)要保持 60 秒呢住册?

因為FIN_WAIT2,TIME_WAIT狀態(tài)都需要保持 2MSL 時長烫葬。MSL 全稱是 Maximum
Segment Lifetime界弧,它定義了一個報文在網(wǎng)絡(luò)中的最長生存時間
(報文每經(jīng)過一次路由器的轉(zhuǎn)發(fā),IP頭部的 TTL 字段就會減 1搭综,減到 0 時報文就被丟棄垢箕,這就限制了報文的最長存活時間)。

為什么是 2 MSL 的時長呢兑巾?這其實是相當于至少允許報文丟失一次条获。比如,若 ACK 在一個 MSL 內(nèi)丟失蒋歌,這樣被動方重發(fā)的 FIN 會在第 2 個 MSL 內(nèi)到達帅掘,TIME_WAIT 狀態(tài)的連接可以應(yīng)對。

為什么不是更長的時間呢堂油?丟包率1%算是糟糕了吧修档,連續(xù)丟兩次呢?我靠府框,1/1W的概率吱窝,還是丟了吧。

因此迫靖,TIME_WAIT 和 FIN_WAIT2 狀態(tài)的最大時長都是 2 MSL院峡,由于在 Linux 系統(tǒng)中,MSL 的值固定為 30 秒系宜,所以它們都是 60 秒照激。

那要怎么優(yōu)化TIME_WAIT狀態(tài)呢?

為什么要優(yōu)化TIME_WAIT盹牧?

之前說到了TIME_WAIT的兩個作用俩垃,還挺得勁,那為什么要優(yōu)化它呢汰寓?(不優(yōu)化他你怎么面試呢吆寨?)

話不是這么說的,你看哈雖然 TIME_WAIT 狀態(tài)有存在的必要踩寇,但它畢竟會消耗系統(tǒng)資源啄清。如果發(fā)起連接一方的 TIME_WAIT 狀態(tài)過多,占滿了所有端口資源俺孙,則會導致無法創(chuàng)建新連接辣卒。

  • 客戶端受端口資源限制:如果客戶端 TIME_WAIT 過多,就會導致端口資源被占用睛榄,因為端口就65536個荣茫,被占滿就會導致無法創(chuàng)建新的連接;
  • 服務(wù)端受系統(tǒng)資源限制:由于一個四元組表示TCP連接场靴,理論上服務(wù)端可以建立很多連接啡莉,服務(wù)端確實只監(jiān)聽一個端口港准,但是會把連接扔給處理線程,所以理論上監(jiān)聽的端口可以繼續(xù)監(jiān)聽咧欣。但是線程池處理不了那么多一直不斷的連接了浅缸。所以當服務(wù)端出現(xiàn)大量 TIME_WAIT時,系統(tǒng)資源被占滿時魄咕,會導致處理不過來新的連接衩椒;

怎么優(yōu)化TIME_WAIT

Linux 提供了 tcp_max_tw_buckets 參數(shù),當 TIME_WAIT 的連接數(shù)量超過該參數(shù)時哮兰,新關(guān)閉的連接就不再經(jīng)歷 TIME_WAIT 而直接關(guān)閉:

調(diào)整timewait最大個數(shù)
echo 5000>/proc/sys/net/ipv4/tcp_max_tw_buckets

當服務(wù)器的并發(fā)連接增多時毛萌,相應(yīng)地,同時處于 TIME_WAIT 狀態(tài)的連接數(shù)量也會變多喝滞,此時就應(yīng)當調(diào)大 tcp_max_tw_buckets 參數(shù)阁将,減少不同連接間數(shù)據(jù)錯亂的概率。

tcp_max_tw_buckets 也不是越大越好右遭,畢竟內(nèi)存和端口都是有限的

有一種方式可以在建立新連接時冀痕,復(fù)用處于 TIME_WAIT 狀態(tài)的連接,那就是打開 tcp_tw_reuse 參數(shù)狸演。但是需要注意言蛇,該參數(shù)是只用于客戶端(建立連接的發(fā)起方),因為是在調(diào)用connect() 時起作用的宵距,而對于服務(wù)端(被動連接方)是沒有用的腊尚。

打開tcp_tw_reuse功能
echo 1>/proc/sys/net/ipv4/tcp_tw_reuse

tcp_tw_reuse 從協(xié)議角度理解是安全可控的,可以復(fù)用處于 TIME_WAIT 的端口為新的連接所用满哪。

什么是協(xié)議角度理解的安全可控呢婿斥?主要有兩點:

  • 只適用于連接發(fā)起方,也就是 C/S 模型中的客戶端哨鸭;
  • 對應(yīng)的 TIME_WAIT 狀態(tài)的連接創(chuàng)建時間超過 1 秒才可以被復(fù)用民宿。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市像鸡,隨后出現(xiàn)的幾起案子活鹰,更是在濱河造成了極大的恐慌,老刑警劉巖只估,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件志群,死亡現(xiàn)場離奇詭異,居然都是意外死亡蛔钙,警方通過查閱死者的電腦和手機锌云,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吁脱,“玉大人桑涎,你說我怎么就攤上這事彬向。” “怎么了攻冷?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵娃胆,是天一觀的道長。 經(jīng)常有香客問我讲衫,道長,這世上最難降的妖魔是什么孵班? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任涉兽,我火速辦了婚禮,結(jié)果婚禮上篙程,老公的妹妹穿的比我還像新娘枷畏。我一直安慰自己,他們只是感情好虱饿,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布拥诡。 她就那樣靜靜地躺著,像睡著了一般氮发。 火紅的嫁衣襯著肌膚如雪渴肉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天爽冕,我揣著相機與錄音仇祭,去河邊找鬼。 笑死颈畸,一個胖子當著我的面吹牛乌奇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播眯娱,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼礁苗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了徙缴?” 一聲冷哼從身側(cè)響起试伙,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎于样,沒想到半個月后迁霎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡百宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年考廉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片携御。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昌粤,死狀恐怖既绕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涮坐,我是刑警寧澤凄贩,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站袱讹,受9級特大地震影響疲扎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捷雕,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一椒丧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧救巷,春花似錦壶熏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至精盅,卻和暖如春帽哑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叹俏。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工祝拯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人她肯。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓佳头,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晴氨。 傳聞我的和親對象是個殘疾皇子康嘉,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容