<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    聶永的博客

    記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。

    TCP協(xié)議缺陷不完全記錄

    零。前言

    TCP自從1974年被發(fā)明出來之后,歷經(jīng)30多年發(fā)展,目前成為最重要的互聯(lián)網(wǎng)基礎(chǔ)協(xié)議。有線網(wǎng)絡(luò)環(huán)境下,TCP表現(xiàn)的如虎添翼,但在移動互聯(lián)網(wǎng)和物聯(lián)網(wǎng)環(huán)境下,稍微表現(xiàn)得略有不足。

    移動互聯(lián)網(wǎng)突出特性不穩(wěn)定:信號不穩(wěn)定,網(wǎng)絡(luò)連接不穩(wěn)定。雖然目前發(fā)展到4G,手機(jī)網(wǎng)絡(luò)帶寬有所增強(qiáng),但因其流動特性,信號也不是那么穩(wěn)定:坐長途公交車,或搭乘城鐵時(shí),或周邊上網(wǎng)密集時(shí)等環(huán)境,現(xiàn)實(shí)環(huán)境很復(fù)雜。

    以下討論基于Linux服務(wù)器環(huán)境,假定環(huán)境為移動互聯(lián)網(wǎng)環(huán)境。記錄我目前所知TCP的一些不足,有所偏差,請給與指正。

    一。三次握手

    在確定傳遞數(shù)據(jù)之前需要三次握手,顯然有些多余,業(yè)界提出了TCP Fast Open (TFO)擴(kuò)展機(jī)制,兩次握手之后就可以發(fā)送正常業(yè)務(wù)數(shù)據(jù)了。但這需要客戶端和服務(wù)器端內(nèi)核層面都支持才行: Linux內(nèi)核3.6客戶端,3.7支持服務(wù)器端。

    進(jìn)階閱讀:TCP Fast Open: expediting web services

    二。慢啟動

    一次的HTTP請求,應(yīng)用層發(fā)送較大HTML頁面的數(shù)據(jù),需要經(jīng)過若干個(gè)往返循環(huán)時(shí)間(Round-Trip Time)之后,擁塞窗口才能夠擴(kuò)展到最大適合數(shù)值,中間過程頗為冗余。這個(gè)參數(shù)直接關(guān)系著系統(tǒng)吞吐量,吞吐量大了,系統(tǒng)延遲小了。但設(shè)置成多大,需要根據(jù)業(yè)務(wù)進(jìn)行抉擇。

    3.0內(nèi)核之前初始化擁塞窗口(initcwnd)大小為3。一個(gè)已建立連接初始傳輸數(shù)據(jù)時(shí)可傳遞3個(gè)MSS,若1個(gè)MSS為1400那么一次性可傳遞4K的數(shù)據(jù),若為10,一次性可傳遞13K的數(shù)據(jù)。

    谷歌經(jīng)過調(diào)研,建議移動互聯(lián)網(wǎng)WEB環(huán)境下建議initcwnd設(shè)置成10,linux內(nèi)核3.0版本之后默認(rèn)值為10。遇到較低內(nèi)核,需要手動進(jìn)行設(shè)置。

    若是局域網(wǎng)環(huán)境有類似大數(shù)據(jù)或文件的傳輸需求,可以考慮適當(dāng)放寬一些。

    若長連接建立之后傳輸?shù)亩际切∠ⅲ看蝹鬏敹M(jìn)制不到4K,那么慢啟動改動與否都是無關(guān)緊要的事情了。

    進(jìn)階閱讀:

    三。線頭阻塞(Head-of-line blocking, HOL)

    TCP協(xié)議數(shù)據(jù)傳輸需要按序傳輸,可以理解為FIFO先進(jìn)先出隊(duì)列,當(dāng)前面數(shù)據(jù)傳輸丟失后,后續(xù)數(shù)據(jù)單元只能等待,除非已經(jīng)丟失的數(shù)據(jù)被重傳并確認(rèn)接收以后,后續(xù)數(shù)據(jù)包才會被交付給客戶端設(shè)備,這就是所謂的線頭(HOL,head-of-line blocking)阻塞。比較浪費(fèi)服務(wù)器帶寬又降低了系統(tǒng)性能,不高效。

    1. 多路復(fù)用不理想

    HTTP/2提出的業(yè)務(wù)層面多路復(fù)用,雖然在一定程度上解決了HTTP/1.*單路傳輸問題,但依然受制于所依賴的TCP本身線頭阻塞的缺陷。構(gòu)建于TCP上層協(xié)議的多路復(fù)用,一旦發(fā)生出現(xiàn)線頭阻塞,需要小心對待多路的業(yè)務(wù)數(shù)據(jù)發(fā)送失敗問題。

    2. TCP Keepalive機(jī)制失效

    理論上TCP的Keepalive保活擴(kuò)展機(jī)制,在出現(xiàn)線頭阻塞的時(shí)候,發(fā)送不出去被一直阻塞,完全失效。

    類似于NFS文件系統(tǒng),一般采用雙向的TCP Keepalive保活機(jī)制,用以規(guī)避某一端因線頭阻塞出現(xiàn)導(dǎo)致Keepalive無效的問題,及時(shí)感知一端存活情況。

    3. 線頭阻塞超時(shí)提示

    數(shù)據(jù)包發(fā)送了,啟動接收確認(rèn)定時(shí)器,超時(shí)后會重發(fā),重發(fā)依然無確認(rèn),后續(xù)數(shù)據(jù)會一直堆積到待發(fā)送隊(duì)列中,這里會有一個(gè)阻塞超時(shí),算法很復(fù)雜。上層應(yīng)用會接收到來自內(nèi)核協(xié)議棧的匯報(bào)"No route to host"的錯(cuò)誤信息,默認(rèn)不大于16分鐘時(shí)間。在服務(wù)器端(沒有業(yè)務(wù)心跳支持的情況下)發(fā)送數(shù)據(jù)前把終端強(qiáng)制斷線,順便結(jié)合TCPDUMP截包,等15分鐘左右內(nèi)核警告"EHOSTUNREACH"錯(cuò)誤,應(yīng)用層面就可以看到"No route to host"的通知。

    四。四次擺手

    兩端連接成功建立之后,需要關(guān)閉時(shí),需要產(chǎn)生四次交互,這在移動互聯(lián)網(wǎng)環(huán)境下,顯得有些多余。快速關(guān)閉,快速響應(yīng),冗余交互導(dǎo)致網(wǎng)絡(luò)帶寬被占用。

    五。確認(rèn)機(jī)制通知到上層應(yīng)用?

    這是一個(gè)比較美好的愿望,上層應(yīng)用在調(diào)用內(nèi)核層接口發(fā)送大段數(shù)據(jù),內(nèi)核完成發(fā)送并且收到對方完整確認(rèn),然后通知上層應(yīng)用已經(jīng)發(fā)送成功,那么在一些環(huán)境下,可以節(jié)省不少業(yè)務(wù)層面交互步驟。

    六。NAT網(wǎng)關(guān)超時(shí)

    IPV4有限,局域網(wǎng)環(huán)境借助于NAT路由設(shè)備擴(kuò)展了接入終端設(shè)備的數(shù)量。當(dāng)建立一個(gè)TCP長連接時(shí),NAT設(shè)備需要維護(hù)一個(gè)內(nèi)部終端連接外部服務(wù)器所使用的內(nèi)部IP:PORT與出去的IP:PORT映射對應(yīng)關(guān)系。這個(gè)關(guān)系需要維護(hù),比較耗費(fèi)內(nèi)存資源,有超時(shí)定時(shí)器清理,否則會導(dǎo)致內(nèi)存撐爆。

    不同NAT設(shè)備超時(shí)值不一樣,因此才需要心跳輔助,確保經(jīng)過NAT設(shè)備的連接一直保持,避免因過長的時(shí)間被踢掉。比如針對中國移動網(wǎng)絡(luò)連接持久時(shí)間一般設(shè)置為不超過5分鐘。各種網(wǎng)絡(luò)略有差異,引入智能心跳機(jī)制比較合適。

    七。終端IP漫游

    手機(jī)終端經(jīng)常在2G/3G/4G和WIFI之間切換,導(dǎo)致IP地址頻繁發(fā)生改變。這樣造成的后果就是已有的網(wǎng)絡(luò)請求-響應(yīng)被放棄和終止,需要人工干預(yù)或重新發(fā)起請求,存在資源浪費(fèi)現(xiàn)象。

    支持Multipath TCP的終端設(shè)備,可以同時(shí)利用 2G/3G/4G 和 WiFi 建立Mutlpath連接,通過多點(diǎn)優(yōu)化網(wǎng)絡(luò)下載,且互為備份。可以很好解決多個(gè)網(wǎng)絡(luò)共存的情況下,一個(gè)網(wǎng)絡(luò)中斷不會導(dǎo)致全局請求處理中斷,在設(shè)備的連接穩(wěn)定和可靠性方面有所增強(qiáng)。

    當(dāng)然,服務(wù)器之間也可以利用Multipath TCP的多個(gè)網(wǎng)絡(luò)增強(qiáng)網(wǎng)絡(luò)吞吐量。

    現(xiàn)狀是:

    1. 目前只有IOS 7以及后續(xù)版本支持
    2. Linux kernel 3.10實(shí)驗(yàn)分支上可以看到其支持身影,但何時(shí)合并到主分支上,暫時(shí)未知

    進(jìn)階閱讀:A closer look at the scientific literature on Multipath TCP

    八。TCP緩存膨脹

    當(dāng)路由器接收到的數(shù)據(jù)包超越其隊(duì)列長度時(shí),一般會隨機(jī)丟包,以減少膨脹。針對上層應(yīng)用程序而言,延遲增加,或誤認(rèn)為數(shù)據(jù)丟失,或連接丟失等。

    遇到這種情況,一般建議快速發(fā)包,以避免丟失的數(shù)據(jù)部分。內(nèi)核層面今早升級到最新版,不低于3.6即可。

    進(jìn)階閱讀:Bufferbloat

    九。TCP不是絕對可靠的

    1. IP和TCP協(xié)議在頭部都會有check sum錯(cuò)誤校驗(yàn)和機(jī)制,16位表示,反碼相加,結(jié)果求反,具體可參考 TCP校驗(yàn)和的原理和實(shí)現(xiàn)。一般錯(cuò)誤很輕松可檢測出來,但遇到兩個(gè)16位數(shù)字相加后結(jié)果不變的情況就一籌莫展了
    2. 以太網(wǎng)幀CRC32校驗(yàn)一般情況下都很OK,但可能遇到兩端隔離多個(gè)路由器情況下,就有可能出現(xiàn)問題,比如陳碩老師提供的一張圖:

      上圖中Client向Server發(fā)了一個(gè)TCP segment,這個(gè)segment先被封裝成一個(gè)IP packet,再被封裝成ethernet frame,發(fā)送到路由器(圖中消息a)。Router收到ethernet frame (b),轉(zhuǎn)發(fā)到另一個(gè)網(wǎng)段(c),最后Server收到d,通知應(yīng)用程序。Ethernet CRC能保證a和b相同,c和d相同;TCP header check sum的強(qiáng)度不足以保證收發(fā)payload的內(nèi)容一樣。另外,如果把Router換成NAT,那么NAT自己會構(gòu)造c(替換掉源地址),這時(shí)候a和d的payload不能用tcp header checksum校驗(yàn)。

    3. 路由器可能偶然出現(xiàn)硬件/內(nèi)存故障導(dǎo)致收發(fā)IP報(bào)文出現(xiàn)多bit/單bit的反轉(zhuǎn)或雙字節(jié)交換,這個(gè)反轉(zhuǎn)如果發(fā)生在payload區(qū),那么無法用鏈路層、網(wǎng)絡(luò)層、傳輸層的check sum查出來,只能通過應(yīng)用層的check sum來檢測。因此建議應(yīng)用層要設(shè)法添加校驗(yàn)數(shù)據(jù)功能。

    4. 大文件下載添加校驗(yàn)保證數(shù)據(jù)完整性,一般采用MD5,也用于防止安全篡改

    參考資料:

    十。小結(jié)

    在這個(gè)滿世界都是TCP的環(huán)境下,要想對TCP動大手術(shù),這個(gè)是不太可能的,因?yàn)樗呀?jīng)固化到已有的系統(tǒng)內(nèi)核和固件中。比如升級終端(比如Android/IOS等)系統(tǒng)/固件,Linux服務(wù)器內(nèi)核,中間設(shè)備/中介設(shè)備(如路由器等),這是一個(gè)浩大工程,目前看也不現(xiàn)實(shí)。

    TCP位于系統(tǒng)內(nèi)核層,內(nèi)核空間的升級、修復(fù),最為麻煩。服務(wù)器端升級還好說一些,用戶終端系統(tǒng)的升級那叫一個(gè)難。用戶空間/用戶核的應(yīng)用升級、改造相對比來說可控性強(qiáng),基于此Google專家們直接在UDP協(xié)議上進(jìn)行構(gòu)建、并且運(yùn)行在用戶空間的QUIC協(xié)議,綜合了UDP的輕量和TCP的可靠性,是一個(gè)比較新穎的方向。

    若是對以后底層傳輸協(xié)議有所期望的話:

    • 在用戶空間(用戶核)出現(xiàn)可以定制的協(xié)議,類似于QUIC
    • 傳統(tǒng)的TCP/UDP可以運(yùn)行在用戶空間,直接略過內(nèi)核
    • 完整協(xié)議棧以靜態(tài)鏈接庫形式提供給上層應(yīng)用
    • 上層應(yīng)用可以在編譯、打包的時(shí)包含其所依賴協(xié)議棧靜態(tài)鏈接庫so文件
    • dpdk/netmap等Packet IO框架 + 用戶空間協(xié)議堆棧,數(shù)據(jù)將從網(wǎng)卡直接送達(dá)上層應(yīng)用
    • Linux內(nèi)核重要性降低,常規(guī)的SSH系統(tǒng)維護(hù)

    雖然TCP存在這樣、那樣的問題,但目前還是無法繞過的網(wǎng)絡(luò)基礎(chǔ)設(shè)施,但稍微明白一些不足的地方,或許會對我們當(dāng)前使用的現(xiàn)狀有所幫助。

    posted on 2015-05-07 14:56 nieyong 閱讀(15581) 評論(3)  編輯  收藏

    評論

    # re: TCP協(xié)議缺陷不完全記錄 2015-05-29 13:26 中國設(shè)計(jì)星

    嗯,這個(gè)很實(shí)用,先收藏了。  回復(fù)  更多評論   

    # re: TCP協(xié)議缺陷不完全記錄 2015-11-05 14:11 ikillmeba

    學(xué)習(xí)學(xué)習(xí)  回復(fù)  更多評論   

    # re: TCP協(xié)議缺陷不完全記錄 2016-05-07 15:06 redsmith

    非常好,贊!  回復(fù)  更多評論   


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    公告

    所有文章皆為原創(chuàng),若轉(zhuǎn)載請標(biāo)明出處,謝謝~

    新浪微博,歡迎關(guān)注:

    導(dǎo)航

    <2015年5月>
    262728293012
    3456789
    10111213141516
    17181920212223
    24252627282930
    31123456

    統(tǒng)計(jì)

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個(gè)人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久久精品国产免费一区| 成人免费无码大片a毛片软件 | 亚洲成人免费在线观看| 亚洲人成网站免费播放| 国产AⅤ无码专区亚洲AV| 免费v片在线观看视频网站| 杨幂最新免费特级毛片| 亚洲国产精品日韩在线观看| 四虎影在线永久免费观看| 亚洲一区二区在线免费观看| 在线观看亚洲免费| 亚洲婷婷综合色高清在线| 亚洲精品成人久久久| 99在线精品免费视频九九视| 黄色短视频免费看| 亚洲人成色77777在线观看| 亚洲日本在线看片| 亚洲精品国产自在久久| 亚欧免费视频一区二区三区| 两性色午夜免费视频| 亚洲色大成网站www久久九| 亚洲va在线va天堂va四虎| 亚洲成a人片在线观看久| 免费在线看v网址| 日本不卡免费新一区二区三区| 国产偷国产偷亚洲高清在线| 亚洲AV无码成人专区| 久久综合图区亚洲综合图区| 免费国产成人高清视频网站| www.免费在线观看| 高清一区二区三区免费视频| 一级一级一级毛片免费毛片| 久久久亚洲精华液精华液精华液| 亚洲国产精品日韩在线| 色婷婷六月亚洲婷婷丁香| 国内精品久久久久久久亚洲| 免费吃奶摸下激烈视频| 日韩精品视频免费观看| 青娱乐免费视频在线观看| 91热成人精品国产免费| 人妻无码久久一区二区三区免费 |