• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            TCP關(guān)閉連接(為什么會(huì)能Time_wait,Close_wait?)

            轉(zhuǎn)載自https://www.qcloud.com/community/article/102

            Tcp關(guān)閉連接問(wèn)題及注意

            最近一段時(shí)間一直在學(xué)習(xí)閱讀mina和nio的源碼,也發(fā)現(xiàn)了一些問(wèn)題無(wú)法解決,然后重讀了一下tcp協(xié)議,收獲頗多。(這就是帶著問(wèn)題去讀書(shū)的好處

            這次就和大家分享一下我們的netframework服務(wù)總會(huì)拋出一個(gè)“connet reset by peer”的原因吧。通過(guò)抓包工具分析,主動(dòng)關(guān)閉方直接發(fā)送了一個(gè)RST flags,而非FIN。就終止連接了。如下圖所示:

            為什么調(diào)用sokcet的close時(shí)只通過(guò)一次握手就終結(jié)連接了?

            要分析這個(gè)原因那就得從關(guān)閉連接程的四次握手,有時(shí)也會(huì)是三次握手,說(shuō)起。如下圖所示:

            大家都知道tcp正常的關(guān)閉連接要經(jīng)過(guò)四次握手。如下所示:

            在這四次握手狀態(tài)中,有一個(gè)特別要注意的狀態(tài)TIME_WAIT這個(gè)狀態(tài)是主動(dòng)關(guān)閉方在收到被關(guān)閉方的FIN后會(huì)處于并長(zhǎng)期(2個(gè)MSL時(shí)間,根據(jù)具體的實(shí)現(xiàn)不同,這個(gè)值會(huì)不同,在RFC 1122建議MSL=2分鐘,但在Berkeley的實(shí)現(xiàn)上使用的值為30s,具體可以看www.rfc.net ,要是沒(méi)有耐心去看英文的可以看這個(gè)網(wǎng)站www.cnpaf.net 里面有協(xié)議說(shuō)明以及相應(yīng)的源碼,java源碼中我沒(méi)有發(fā)現(xiàn)這個(gè)值,我只能追蹤到PlainSocketImpl.java這個(gè)類,再往下就是本地接口調(diào)用了,因此它是依賴本地操作系統(tǒng)的實(shí)現(xiàn))處于的一個(gè)狀態(tài)也就是大約1-4分鐘,然后由操作系統(tǒng)自動(dòng)回收并將TCP連接設(shè)為CLOSED初始狀態(tài)。如下圖所示:

            然而在socket的處于TIME_WAIT狀態(tài)之后到它結(jié)束之前,該socket所占用的本地端口號(hào)將一直無(wú)法釋放,因此服務(wù)在高并發(fā)高負(fù)載下運(yùn)行一段時(shí)間后,就常常會(huì)出現(xiàn)做為客戶端的程序無(wú)法向服務(wù)端建立新的socket連接的情況,過(guò)了1~4分鐘之后,客戶又可以連接上了,沒(méi)多久又連接不上,再等1~4分鐘之后又可以連接上,(上一個(gè)星期我們?cè)谧鲆粋€(gè)服務(wù)切換時(shí)遇到了這種情況)

            這是因?yàn)榉?wù)方socket資源已經(jīng)耗盡。netstat命令查看系統(tǒng)將會(huì)發(fā)現(xiàn)機(jī)器上存在大量處于TIME_WAIT狀態(tài)的socket連接,我這邊曾經(jīng)出現(xiàn)達(dá)到了2w多個(gè),并且占用大量的本地端口號(hào)。而此時(shí)機(jī)器上的可用本地端口號(hào)被占完,舊的大量處于TIME_WAIT狀態(tài)的socket尚未被系統(tǒng)回收時(shí),就會(huì)出現(xiàn)無(wú)法向服務(wù)端創(chuàng)建新的socket連接的情況。只能過(guò)2分鐘之后等系統(tǒng)回收這些socket和端口資源之后才能服務(wù),就這樣往復(fù)下去。

            TCP為什么要這么要讓這種TIME_WAIT狀態(tài)存活這么久呢?其原因有兩個(gè)(參考stevens的unix網(wǎng)絡(luò)編程卷1 第38頁(yè)):

            1. 可靠地實(shí)現(xiàn)TCP全雙工連接的終止。(確保最后的ACK能讓被關(guān)閉方接收)
            2. 允許老的重復(fù)分節(jié)在網(wǎng)絡(luò)中消逝。(TCP中是可靠的服務(wù),當(dāng)數(shù)據(jù)包丟失會(huì)重傳,當(dāng)有數(shù)據(jù)包迷路的情況下,如果不等待2MSL時(shí),當(dāng)客戶端以同樣地方式重新和服務(wù)建立連接后,上一次迷路的數(shù)據(jù)包這時(shí)可能會(huì)到達(dá)服務(wù),這時(shí)會(huì)造成舊包被重新讀取)

            解決方法:

            1、(推薦方法,只能治標(biāo)不治本)重用本地端口設(shè)置SO_REUSEADDR和SO_REUSEPORT(stevens的unix網(wǎng)絡(luò)編程卷1 第179~182頁(yè))有詳情的講解,這樣就可以允許同一端口上啟動(dòng)同一服務(wù)器的多個(gè)實(shí)例。怎樣理解呢?說(shuō)白了就是即使socket斷了,重新調(diào)用前面的socket函數(shù)不會(huì)再去占用新的一個(gè),而是始終就是一個(gè)端口,這樣防止socket始終連接不上,會(huì)不斷地?fù)Q新端口。Java 中通過(guò)調(diào)用Socket的setReuseAddress,詳細(xì)可以查看java.net.Socket源碼。【這個(gè)地方會(huì)有風(fēng)險(xiǎn),具體可以看(stevens的unix網(wǎng)絡(luò)編程卷1 第181頁(yè))

            2、修改內(nèi)核TIME_WAIT等待的值,如果客戶端和服務(wù)器都在同個(gè)路由器下,這個(gè)是非常推薦的。(鏈路好,重傳機(jī)率低)

            3、(不推崇,但目前我們是這樣做的,這個(gè)是造成(“connet reset by peer”)的元兇)設(shè)置SO_LINGER的值,java中是調(diào)用socket的 setSoLinger目前我們是設(shè)置為0的。設(shè)置為這個(gè)值的意思是當(dāng)主動(dòng)關(guān)閉方設(shè)置了setSoLinger(true,0)時(shí),并調(diào)用close后,立該發(fā)送一個(gè)RST標(biāo)志給對(duì)端,該TCP連接將立刻夭折,無(wú)論是否有排隊(duì)數(shù)據(jù)未發(fā)送或未被確認(rèn)。這種關(guān)閉方式稱為“強(qiáng)行關(guān)閉”,而后套接字的虛電路立即被復(fù)位,尚未發(fā)出的所有數(shù)據(jù)都會(huì)丟失。而被動(dòng)關(guān)閉方卻不知道對(duì)端已經(jīng)徹底斷開(kāi)。當(dāng)被動(dòng)關(guān)閉方正阻塞在recv()調(diào)用上時(shí),接受到RST時(shí),會(huì)立刻得到一個(gè)“connet reset by peer”的異常(即對(duì)端已經(jīng)關(guān)閉),c中是返回一個(gè)EPEERRST錯(cuò)。

            為什么不推崇這種方法在(stevens的unix網(wǎng)絡(luò)編程卷1 第173頁(yè))有詳細(xì)的講解。因?yàn)門IME_WAIT狀態(tài)是我們的朋友,它是有助有我們的(也就是說(shuō),它會(huì)讓舊的重復(fù)分節(jié)在網(wǎng)絡(luò)中超時(shí)消失(當(dāng)我們的鏈路越長(zhǎng),ISP復(fù)雜的情況下(從網(wǎng)通到教育網(wǎng)的ping包用了9000ms),重復(fù)的分節(jié)的比例是非常高的。))。而且我們主動(dòng)關(guān)閉連接方大都是由客戶端發(fā)起的(除了HTTP服務(wù)和異常),而且客戶方一般都不會(huì)有持續(xù)的大并發(fā)請(qǐng)求。 因此對(duì)資源沒(méi)有這么苛刻要求。

            轉(zhuǎn)載請(qǐng)注明出處: 騰云閣 https://www.qcloud.com/community

            posted on 2016-11-02 10:03 楊粼波 閱讀(982) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久精品国产亚洲AV无码| 久久精品毛片免费观看| 久久Av无码精品人妻系列| 久久精品免费大片国产大片| 久久国产精品一区二区| 久久福利青草精品资源站免费| 97久久久精品综合88久久| 久久精品国产亚洲av日韩| AV无码久久久久不卡网站下载| 成人国内精品久久久久一区| www.久久精品| 国产综合精品久久亚洲| 婷婷久久精品国产| 亚洲中文字幕无码久久综合网| 亚洲精品乱码久久久久久中文字幕| 久久这里有精品| 久久影院综合精品| 国产精品免费久久| 亚洲精品成人网久久久久久| 午夜天堂精品久久久久| 国内精品久久久久久久97牛牛| 青青青国产成人久久111网站| 久久综合久久鬼色| 久久99精品久久久久子伦| 88久久精品无码一区二区毛片| 久久九九久精品国产| 久久亚洲AV无码精品色午夜麻豆| 韩国免费A级毛片久久| 精品无码久久久久久国产| 伊人 久久 精品| 69SEX久久精品国产麻豆| 天天综合久久一二三区| 精品久久久久久成人AV| 久久综合一区二区无码| 久久综合久久自在自线精品自| 久久精品国产一区二区| 久久天天躁狠狠躁夜夜96流白浆| 久久久91人妻无码精品蜜桃HD| 久久天堂AV综合合色蜜桃网| 久久午夜综合久久| 女人香蕉久久**毛片精品|