一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

干貨!史上最全的CDN內(nèi)容分發(fā)網(wǎng)絡(luò)實(shí)戰(zhàn)技巧(上)

 nzpeach 2017-05-19

整理自【微學(xué)堂】第二十四期課程實(shí)錄


嘉賓介紹

白金,ChinaUnix 資深版主,曾擔(dān)任《iptables 高級使用研討》講師,精通iptables模塊的開發(fā)和netfilter內(nèi)核開發(fā),擅長協(xié)議識別技術(shù)及網(wǎng)絡(luò)攻擊防御技術(shù)。


直播實(shí)錄


大家好,,我叫白金(真名),很高興今天來給大家做個分享。在 CU 混了大概 10 年,ID 是 platinum,原在藍(lán)汛(ChinaCache)工作,現(xiàn)在在光載無限,目前擔(dān)任架構(gòu)部總監(jiān)的職位。


今天來給大家分享下關(guān)于 CDN 的東西,以及我自己的一些發(fā)現(xiàn)、一些個人的拙見。總共分為 3 個部分:原理、詳解、各種坑。



首先說一下 CDN 的基本原理部分,主要分 4 塊來描述:CDN 的由來、調(diào)度是怎么做的、緩存是什么、關(guān)于安全。



最初剛有互聯(lián)網(wǎng)的時候,帶寬用量不多、用戶少,并不存在什么問題,后來隨著發(fā)展,逐漸出現(xiàn)了使用量大、訪問緩慢的情況。最初 95 年的時候,有兩個博士試圖通過利用數(shù)學(xué)的辦法來解決動態(tài)路由問題,且效果還不錯,這便是 Akamai 的前身,也是全球第一個CDN 公司。98 年中國成立了國內(nèi)第一家 CDN 公司,藍(lán)汛,ChinaCache,很榮幸我曾在這個公司任職,群里也有好多前藍(lán)汛的同事們,也有很多現(xiàn)還在藍(lán)汛的同事。



什么是 CDN?


這是一個做過 CDN 之后的拓?fù)鋱D,里面有幾個概念需要明確一下:

Origin Server: 源站,也就是做 CDN 之前的客戶真正的服務(wù)器;

User: 訪問者,也就是要訪問網(wǎng)站的網(wǎng)民;

Edge Server: CDN 的服務(wù)器,不單只“邊緣服務(wù)器”,這個之后細(xì)說;

s/\(單\)只/\1指/;

Last Mile: 最后一公里,也就是網(wǎng)民到他所訪問到的 CDN 服務(wù)器之間的路徑。


我們平時所使用的DNS服務(wù)器,一般稱之為LDNS,在解析一個域名的時候,一般有兩個情況,一種是域名在DNS上有記錄,另一種情況是沒有記錄,兩種情況的處理流程不一樣。


當(dāng)你訪問163這個域名時,如果LDNS上有緩存記錄,那它會直接將IP地址直接給你。如果沒有緩存記錄,它將會一步步向后面的服務(wù)器做請求,然后將所有數(shù)據(jù)進(jìn)行匯總交給最終的客戶。


當(dāng)你訪問163這個地址時,實(shí)際上如果本身沒有內(nèi)容的話,它要去后面拿數(shù)據(jù),這個過程術(shù)語叫遞歸,它首先會向全球13個根域服務(wù)器請求,問com域名在哪,然后根域服務(wù)器作出回答,一步步往下,這個過程較復(fù)雜,如果大家感興趣可去查相關(guān)資料,在這就不一一贅述。



DNS調(diào)度


肯定很多人好奇是如何進(jìn)行調(diào)度和進(jìn)行定位的?

其實(shí)也是通過LDNS的具體地址來進(jìn)行的,比如,看圖,假設(shè)你是一個廣東電信客戶,那你所使用的DNS服務(wù)器去做遞歸的時會訪問到某一個CDN廠商的GRB,全球的一個調(diào)度系統(tǒng),他就能看到來自于哪個LDNS。假設(shè)如果用戶和LDNS使用同一個區(qū)域的服務(wù)器,他就會間接認(rèn)為用戶也是廣東電信的。


再舉個例子,比如說北京聯(lián)通的用戶,它使用DNS地址,一般自動給它分配的是北京聯(lián)通的服務(wù)器,這個服務(wù)器去做遞歸的時候,調(diào)度服務(wù)器就會看到這個請求是來自北京聯(lián)通的LDNS服務(wù)器,就會給它分配一個北京聯(lián)通的服務(wù)器地址,然后讓來自北京聯(lián)通的用戶直接訪問北京聯(lián)通的服務(wù)器地址,這樣來實(shí)現(xiàn)精準(zhǔn)的區(qū)域性調(diào)度。


從這個調(diào)度理論上看,我們可以發(fā)現(xiàn)一個問題,就是假設(shè)用戶所使用的LDNS地址和你是同一個區(qū)域,那么這個時候我們的調(diào)度才有可能是正確的。但是舉個例子來說,如果你是北京聯(lián)通的用戶,可是使用的是廣東電信的LDNS的話,就會讓GRB系統(tǒng)誤以為你是廣東電信的客戶,這樣就會錯誤的調(diào)度過去。


之前有一次我在小區(qū)里上網(wǎng),由于我的路由器有問題,我設(shè)了202.106.0.20的北京聯(lián)通的DNS服務(wù)器地址,后來出差去深圳,訪問比較大的網(wǎng)站發(fā)現(xiàn)比較慢,經(jīng)過分析,才發(fā)現(xiàn)原來我設(shè)的DNS地址是北京聯(lián)通的,而我在廣東和深圳使用的網(wǎng)絡(luò)都是電信接入的,但是分配給我的是北京聯(lián)通的地址,那我用電信的線路訪問北京聯(lián)通的地址,勢必就會很慢。



因?yàn)閯偛胖v到的DNS調(diào)度機(jī)制存在一定問題,所以在某些場合下我們會使用第二種調(diào)度機(jī)制,叫HTTP的調(diào)度。


了解http協(xié)議的人知道,在http協(xié)議中有一個叫302跳轉(zhuǎn)的功能,它的實(shí)現(xiàn)并不是說你訪問一個URL,然后馬上吐給你想要的數(shù)據(jù),而是吐給你一個302返回信令,這個信令頭部會告訴你,有一個location目標(biāo),這個location就是告訴你下一步將要怎么做,而具體調(diào)度是通過location來實(shí)現(xiàn)的。


即便我所使用的DNS和我不在一個區(qū)域,但當(dāng)我訪問http server的時,這個server是由CDN公司提供的??蛻粼L問server的時,雖說通過DNS方式無法拿到客戶的真正IP地址,但是如果你訪問的是http server,他一定能直接看到客戶的真實(shí)IP,利用這種方法可以進(jìn)行調(diào)度的糾偏,可以直接返回給你一個302,然后location里面攜帶一個真正離你最近的CDN server。


這種調(diào)度方式,優(yōu)勢是準(zhǔn)確,但是也存在弊端,它需要有一次TCP的三次握手建連,他不像DNS那樣直接請求一個數(shù)據(jù)包過去給一個反饋就OK了,他需要一次TCP的三次握手建連。


第二個是你如何訪問到http的服務(wù)器?如果你之前是通過DNS調(diào)度過去的,實(shí)際上前邊的那個DNS也是省不了,在國內(nèi)是沒有辦法做anycast的,也就是沒有辦法來直接訪問一個眾所周知的大的IP來進(jìn)行,所以,一般情況下都是通過DNS來進(jìn)行第一次調(diào)度,然后用http來進(jìn)行第二次糾偏。這種情況下大家可以想象,如果你下載一個大文件,比如說電影,但你訪問的是一個頁面小元素,比如說這個圖片只有幾k,那么,實(shí)際上你調(diào)度的時間就已占用了很大的成分。實(shí)際上,這種302調(diào)度是一種磨刀不誤砍柴工的方案,如果你后面有很多工作要做,比如要下載一個電影時間會很長,那你調(diào)度準(zhǔn)確,即使花一點(diǎn)時間調(diào)度也是值得的。但是如果你后續(xù)訪問一下就完了,那么你這樣調(diào)度就沒有太大意義。



除了DNS調(diào)度和http的302調(diào)度以外,其實(shí)還有一種調(diào)度方式,叫http DNS調(diào)度,它的原理是通過一個正常的http請求,發(fā)一個get的請求,然后再請求里面以參數(shù)的形式攜帶一個我要解析的域名,然后服務(wù)器那邊去通過數(shù)據(jù)庫查詢,查詢之后又通過http的正常響應(yīng),把這個你要請求的IP通過http協(xié)議給你,這種協(xié)議有一個特點(diǎn)就是必須雙端都支持,因?yàn)檫@種模式是非標(biāo)準(zhǔn)的。沒有任何一個RFC文檔說,你的客戶端或者你的操作系統(tǒng)天生就支持這種機(jī)制。這有點(diǎn)類似是一種API的這種方式,那如果要實(shí)現(xiàn)的話就必須雙端都支持。


一般,第三種調(diào)度的應(yīng)用場景是在手機(jī)的APP端,在APP軟件里面,你要訪問某些東西很有可能被運(yùn)營商劫持等問題,這個劫持問題后面還有很大的篇幅去講。那為了避免這種劫持,可能會用到這種http DNS的調(diào)度方式。既然APP的程序都是你自己寫的,所以說實(shí)現(xiàn)這么簡單一個API的借口是很容易的。



CDN的接入


可能會有人問,你講了這么多DNS和具體CDN的調(diào)度有什么關(guān)系呢?


因?yàn)樵谥v你獲得一個具體的DNS域名地址的時,他給你的就是一個IP地址。那在沒有CDN之前,他給你的IP地址就是在原來沒做CDN時的原始服務(wù)器地址。但如果你做過CDN的話,你會發(fā)現(xiàn)最終拿到的這個IP地址是CDN的節(jié)點(diǎn),而并不是真正的原始服務(wù)器。


我們通常說的拿到一個IP地址,這實(shí)際上是DNS的A記錄。DNS里面有很多不同的記錄,比如像A記錄負(fù)責(zé)給你一個IP地址;比如像CNAME記錄給你的是一個域名的別名。當(dāng)然還有很多其他記錄,比如TXT的記錄、MX記錄等等。這個跟CDN無關(guān),這里就不細(xì)說了,有興趣去查一下DNS相關(guān)的文檔。


上圖就是一個很明顯的CDN介入后的效果圖。linux里有一個命令叫dig,它可直接把要訪問域名的具體的解析情況列出來。那么,通過這個圖可看出,當(dāng)你要訪問www.163.com時,他最終雖給出的是一個IP地址,但實(shí)際上,它經(jīng)過了兩次CNAME記錄。第一次CNAEM記錄就是我們之前說得CDN的GRB,他拿到了這個數(shù)據(jù),就可以間接知道你的這個LOCODNS是從哪里來的,然后間接給你進(jìn)行一個定位。以這個圖為例,他實(shí)際上第一跳是跳到網(wǎng)速地址,第二跳是分配了網(wǎng)速的一個平臺,這個平臺又分開其他的IP給最終的客戶。



Cache 系統(tǒng)—緩存系統(tǒng)


除DNS調(diào)度以外,在CDN里還有一個非常大的重頭戲就是Cache系統(tǒng),也就是緩存系統(tǒng)。它用于把那些可以緩存住的東西,緩存到CDN的邊緣節(jié)點(diǎn),這樣當(dāng)?shù)诙€人去訪問同一節(jié)點(diǎn),同一具體電影或MP3時就不用再經(jīng)過CDN鏈路回到真正的源站去拿數(shù)據(jù),而是由邊緣節(jié)點(diǎn)直接給數(shù)據(jù)。


在Cache系統(tǒng)里囊括了很多的技術(shù),比如,用空間換時間的這種高效的數(shù)據(jù)結(jié)構(gòu)和算法,多級緩存以熱度來區(qū)分,前端是SSD后面是機(jī)械硬盤等等。很多的細(xì)節(jié)就不說了,如感興趣的可之后交流。



對于Cache系統(tǒng)來說,有兩種不同的工作狀態(tài)。第一種工作狀態(tài)就是所謂的命中(hit),第二種就是沒有命中(miss)。如果命中了,直接通過檢索找到磁盤或內(nèi)存上的數(shù)據(jù),把這個數(shù)據(jù)直接吐給客戶,而不是從后面去拿數(shù)據(jù)。這樣的話就起到一個很完美的加速效果。



第二種是在miss時,其實(shí),miss的時候跟hit唯一的區(qū)別就是,當(dāng)我發(fā)現(xiàn)我的本機(jī)上沒有這個資源,我會去我的upstream(上游)去拿數(shù)據(jù)。拿完這個數(shù)據(jù),除了第一時間給客戶,同時還會在硬盤上緩存一份。如果這個硬盤空間滿了,會通過一系列置換方法,把最老的數(shù)據(jù)、最冷的數(shù)據(jù)替換出去。


提到了upstream,不是原始服務(wù)器,原因是因?yàn)楫?dāng)客戶訪問到CDN節(jié)點(diǎn)的時,他發(fā)現(xiàn)上面沒有數(shù)據(jù),并不是直接從原始服務(wù)器上去拿,而是經(jīng)過他的另一個CDN節(jié)點(diǎn),然后通過middlemell的方式去進(jìn)行一些數(shù)據(jù)傳輸。然后upstream這一層,從原始服務(wù)器拿數(shù)據(jù),通過一系列的加速手段,快速的把數(shù)據(jù)投遞給我們的邊緣節(jié)點(diǎn),再把這個數(shù)據(jù)給最終客戶。在過程當(dāng)中upstream和downstream這兩層都會把數(shù)據(jù)緩存一份。通過這種樹形結(jié)構(gòu),比如說多個邊緣節(jié)點(diǎn),然后匯總到一個或者幾個副層結(jié)點(diǎn),這樣的話可以逐漸的實(shí)現(xiàn)流量的收斂。



提到Cache的具體技術(shù),我相信這里的很多朋友都是同行業(yè)的,有人會說其實(shí)這沒有什么難的,你只要有網(wǎng)絡(luò)、有運(yùn)維人員就可以了。其實(shí)我并不這樣認(rèn)為,因?yàn)槟闳绻氚阉龊玫脑捚鋵?shí)很難,比如,我列出的很多技術(shù)你有沒有在考慮?


舉幾個例子來說,你有沒有做網(wǎng)卡的的多隊(duì)列和CPU的親和性綁定?你有沒有做磁盤的調(diào)度算法改進(jìn)?另外,你存儲的時候還是用還是?等等都是有講究的。包括內(nèi)核的調(diào)優(yōu)包括架構(gòu)和CPU的綁定,CPU的多級緩存的使用,然后你的處理你使用,還是用標(biāo)準(zhǔn)的的這種機(jī)制。再比如說編譯的程序時使用的去編譯還是用英特爾的,然后你再做很多的調(diào)用。比如說一個很簡單的字符串拷貝,那你是用,你還是用匯編去寫,你還是用什么方式等等很多細(xì)節(jié)。


關(guān)于高性能這一塊,還有很多的研究,如大家感興趣的話,可以之后跟我進(jìn)行進(jìn)一步的溝通。我想表達(dá)的一個觀點(diǎn)就是說,看上去做CDN很簡單,入門確實(shí)也簡單,但是要真正想做好很難。



安全問題


在沒有做CDN之前你的網(wǎng)站很有可能會遭受到各種各樣的攻擊。那么攻擊一般分成兩種,第一種叫蠻力型攻擊,量大的讓你的帶寬無法抗住最后導(dǎo)致拒絕服務(wù),另外一種是技巧性攻擊。


作為CDN來講,就已經(jīng)將你的原始服務(wù)器的IP進(jìn)行了隱藏。這樣當(dāng)一個攻擊者去訪問你的域名的時,實(shí)際上訪問的并不是你真正的服務(wù)器。當(dāng)他訪問的是CDN的節(jié)點(diǎn),就沒有辦法把CDN的節(jié)點(diǎn)打倒,換句話說,即使有能力把CDN的比如10g的節(jié)點(diǎn)或者是40g的大節(jié)點(diǎn)全部打倒,但由于CDN天然的分布式的部署方式,他也很難在同一時間之內(nèi)迅速的把全國所有CDN的邊緣節(jié)點(diǎn)全都打癱。


另外,還有一種攻擊是針對你的DNS地址的。如果你的GRB癱了的話,會導(dǎo)致整個調(diào)度系統(tǒng)失靈。如果調(diào)動系統(tǒng)失靈,即使你的CDN的Cache server還是能夠正常接受請求,但由于流量調(diào)度不了。因此,你需要在DNS層做很多防護(hù)機(jī)制,比如說用高性能的DNS或用分布式的部署方式等等。



技巧型攻擊不需要很大的流量,就可以把你的原針打倒或是讓你的網(wǎng)頁出現(xiàn)錯誤的情況。比如說,像注入、掛馬甚至說更嚴(yán)重的會直接拖走你的數(shù)據(jù)庫等等。那么作為CDN來說,有很多廠商實(shí)際上已經(jīng)開始具備這樣的技巧性的防護(hù)能力了,比如說WAF(Web Application Fierwall),就是應(yīng)用層防火墻,他可以直接去解析你的請求內(nèi)容,分析內(nèi)容是否有惡意性,如有惡意性的話去進(jìn)行過濾,報警等一系列措施來保證你的原始服務(wù)器的安全。


詳解篇


第二部分主要是針對網(wǎng)絡(luò)層的優(yōu)化、架構(gòu)的優(yōu)化、Cache的選型還有性能分析等等幾個方面,對整個CDN的基礎(chǔ)原理作很深入地剖析。



原始的CDN其實(shí)是Content Delivery Network這三個詞的縮寫,也就是內(nèi)容分發(fā)網(wǎng)絡(luò)。但我認(rèn)為應(yīng)該是can do something on Network。CDN的理念是加速,所以,我們就盡一切可能去做各種優(yōu)化,從一層到七層的優(yōu)化來實(shí)現(xiàn)最終的優(yōu)化效果。


為什么說一層是優(yōu)化,實(shí)際上也是硬件,你的服務(wù)器選型就是一種優(yōu)化。你是用ssd,還是用saker硬盤,你是該用pce卡,還是應(yīng)該用ssd。你的CPU應(yīng)該用至強(qiáng)還是應(yīng)該用阿童木的等等,都是需要去斟酌。


至于二層,鏈路層的優(yōu)化指的就是資源方面。比如機(jī)房如何去選擇。


三層路由層是指你在middlemell這塊真正選路的具體的細(xì)節(jié),后面會有一個圖來具體講一下。


四層是指傳輸層的優(yōu)化,我們一般的業(yè)務(wù)全都是TCP,所以說這里面就可以明確的說這里是指TCP的優(yōu)化。還有一個就是七層也是可以優(yōu)化的。比如說你強(qiáng)行對內(nèi)容進(jìn)行壓縮,甚至你改變壓縮級別去壓縮。



作為CDN來說,基本上我羅列了一下可能會用到的一些技術(shù),大概10個。比如說就近分布、策略性的緩存、傳輸?shù)膬?yōu)化、鏈路層的優(yōu)化、包括內(nèi)容的預(yù)取、合并回源。然后持久連接池、主動壓縮,還有當(dāng)你原始服務(wù)器掛了的話你怎么樣能夠保證讓客戶看到數(shù)據(jù)等很多的細(xì)節(jié)。



路徑的優(yōu)化,實(shí)際上,我們可以把它抽象成是一個求最短路徑最優(yōu)解的思路去解決真實(shí)的問題。當(dāng)你從a點(diǎn)到b點(diǎn)需要傳輸數(shù)據(jù)的時,往往會經(jīng)過一個c點(diǎn),比直接從a到b更快。在互聯(lián)網(wǎng)里有個三角原理,和地理位置的原理有一定區(qū)別的。雖說有一定的相關(guān)性,但還是有區(qū)別的,有可能從a經(jīng)過c到b會比a直接到b更快。


在數(shù)據(jù)傳輸?shù)臅r,需要去考慮很多綜合因素,目前為止,包括阿克麥也很難做到完全系統(tǒng)自動化去做鏈路選擇和切換。在調(diào)度的時,很多公司都有專門的團(tuán)隊(duì)管流量調(diào)度的。很多的系統(tǒng)可能只起到支撐和參考的作用,而真正需要決策的還是人。因?yàn)槟阈枰紤]的元素太多了,比如說要考慮你的帶寬成本、帶寬節(jié)點(diǎn)冗余量、服務(wù)器承載能力,要考慮你的客戶敏感度哪些該切哪些不該切等很多細(xì)節(jié)。



傳輸層的優(yōu)化剛才講到了是TCP優(yōu)化,在現(xiàn)今的互聯(lián)網(wǎng)里,TCP優(yōu)化是可以帶來最直接客戶體驗(yàn)感的一種實(shí)現(xiàn)方式。如果想講TCP優(yōu)化到底是怎么回事,我們就得先從頭講一下TCP具體的原理是怎樣的。


上圖,我畫了四個不同的紅圈,cwnd,英文是,就是擁塞控制窗口,用途是控制發(fā)送端的發(fā)送速度。ss是slow start的縮寫,也就是慢啟動,這是任何一個TCP協(xié)議在最開始的時候必經(jīng)的一個階段。


后兩個詞較有意思,ssthresh,是slow start threshold的縮寫,也就是說慢啟動閾值。它是出現(xiàn)在你傳輸?shù)揭欢ㄋ俣鹊臅r,認(rèn)為應(yīng)慢點(diǎn)去傳的時,原來的指數(shù)傳輸方式,增長速度方式變成現(xiàn)行的速度增長,來盡量的規(guī)避和避免網(wǎng)絡(luò)的擁塞。


那整個擁塞避免階段其實(shí)就是圖中右下角的CA,這是擁塞避免這個線性的過程,不是指數(shù)。指數(shù)的那個叫慢啟動。


當(dāng)TCP開始傳輸數(shù)據(jù)的時,最開始的時候并不是以一個很快的速度發(fā)出。你看到的wget或是下載某一個東西的速度猛的就非???,實(shí)際上它是一個由微觀慢慢把速度加起來的過程,只是這個時間很短你可能并沒有察覺。但實(shí)際上從微觀上來看最開始是有一個所謂的初始發(fā)包數(shù)量的這么一個概念。在早期的2.6.18內(nèi)核,也就是3645相對應(yīng)的這個版本之前,初始的發(fā)包數(shù)量是兩個。


它發(fā)出第一輪數(shù)據(jù),實(shí)際上只發(fā)兩個數(shù)據(jù)包。等待這兩個數(shù)據(jù)包的完全確認(rèn),如這兩個數(shù)據(jù)包完全收到ACK確認(rèn)數(shù)據(jù)之后,會認(rèn)為第一輪數(shù)據(jù)你都已經(jīng)收到了,這時它會把發(fā)包的數(shù)量調(diào)整成4個。如果第二個也收到了,就調(diào)成8個16個32個這樣的一個增長過程,就是slow start的過程。那這個過程實(shí)際上就是一個最開始在TCP剛開始建立的時候的一個最初始的過程。


那這個過程什么時候會結(jié)束?其實(shí)就是在丟包的時候。如果沒有丟包,我沒有理由降速或者調(diào)整發(fā)送速度。當(dāng)他遇到丟包的時候他就會把這個值記錄下來,并且通過他的擁塞控制算法,算出一個合理的閾值。那么當(dāng)下一次速度增長到這個閾值的時候,就會知道不能再指數(shù)增長了,而是應(yīng)該線性的增長發(fā)包的數(shù)量,來避免再次丟包。


還有個概念就是RTO,實(shí)際上是在服務(wù)器發(fā)數(shù)據(jù)而客戶端始終沒有響應(yīng)的時,它會等待一個超時定時器。這個超時定時器一旦出現(xiàn),就會回到另一個協(xié)議棧里的一個狀態(tài)機(jī)。當(dāng)這個狀態(tài)機(jī)處于丟包狀態(tài)時,它就會把它的CWND降到最開始這么大,那么他的速度就會驟降,這是個非常嚴(yán)重的問題。且一旦驟降它會重新評估。有可能,你之前,比如說你的窗口長到24,但是你丟包了,然后他給你算出你應(yīng)該到16就變成線性。如果你再出現(xiàn)嚴(yán)重問題,它可能會把閾值降到12,并啟用線性傳輸模式了。

通過介紹這個原理,大家可能會看到,其實(shí)TCP是一個很聰明的做法。它在能盡量傳的時候拼命的提高速度,然后在丟包的時候就盡量降低速度,盡量的規(guī)避擁堵。


現(xiàn)如今的網(wǎng)絡(luò)產(chǎn)生了很大不同,因?yàn)?,比如說WiFi的接入、3G、4G的移動信號的接入,甚至南電信北聯(lián)通的一些資源的不充沛,更甚至是惡意的一些限速,會導(dǎo)致你丟包的原因,有時并不是真正的擁塞。而是你鏈路里面命中注定會有這么多的數(shù)據(jù)會丟掉。

 

大家想象一下,假如有一個恒定的丟包概率的網(wǎng)絡(luò)。當(dāng)我發(fā)一百個包的時候,丟掉百分之二十,只收到了八十個,這時如果去降速,就意味著降得速度越低,發(fā)送的數(shù)據(jù)量就越小,那么對端收到的就更少。因?yàn)閬G包概率是恒定的,如果遇到這種情況的話,早期的TCP的擁塞控制算法就已經(jīng)不能滿足現(xiàn)有的這種環(huán)境的需求了,因此我們要考慮如何去優(yōu)化。



這是用tcpdump把數(shù)據(jù)包抓下來后用Verashape軟件打開并且進(jìn)行圖形化分析的一個微觀展示圖。


圖里可以看到另外一個細(xì)節(jié),就是能看到有很多不同的這種發(fā)包的周期。這個其實(shí)就是我剛才講的每次發(fā)兩個、四個、八個、十六個這樣的不同的發(fā)送的時刻。但這里有個問題,他發(fā)送時會一股腦兒地把數(shù)據(jù)發(fā)出去。雖說在宏觀上來講,你單位時間之內(nèi)只能發(fā)這么多,但是從微觀上來講,實(shí)際上你這么一次發(fā)送就相當(dāng)于是burst,這種大的沖擊有可能會導(dǎo)致中間網(wǎng)絡(luò)鏈路不充沛,然后會造成丟包。


在早期研究GPRS網(wǎng)絡(luò)或者是25G的網(wǎng)絡(luò)的時候,尤其會遇到這種情況。他的特征是RTT很長,同時你的帶寬很小。那大家可以想象一下,如果你的帶寬很小,每一次突發(fā)這么大,從微觀角度來講,這個數(shù)據(jù)就已經(jīng)有可能會造成微觀上的丟包了。



另外一種優(yōu)化的方法就是的平滑發(fā)包,充分的利用每一個發(fā)包周期之間的時間間隔,然后把數(shù)據(jù)包打散。這樣的話,既沒有讓對方從宏觀上感覺發(fā)送速度慢,從微觀上我也讓這個數(shù)據(jù)變得更平滑,而不會導(dǎo)致某一個具體的小時間的一個時刻,由于鏈路不充足而導(dǎo)致丟包。



除了剛才說的以外,還有很多優(yōu)化的方法。比如說建連優(yōu)化,當(dāng)你去發(fā)信包三次握手的時,默認(rèn)情況下,對方如果未反饋,你會以1為一個貝司值然后以2的主數(shù)遞增這樣去重試。比如,一秒鐘重試一次,兩秒鐘一次,四秒鐘一次,很多次之后,它會自動的放棄。那如果按照6.18內(nèi)核,以3為一個貝司值,以3的主數(shù)遞增,三、六、十二這樣。所以,這個環(huán)節(jié)就可能會導(dǎo)致很嚴(yán)重的問題,那對服務(wù)器來說你可以做到什么?比如說你再發(fā)完這個CS第二次握手之后,如果他一段時間沒響應(yīng),可快速給他再重發(fā)一遍。


這種數(shù)據(jù)包的優(yōu)化實(shí)際上并不會占用什么網(wǎng)絡(luò),而且有可能會勾引出第三次握手,快速的解決由于你的服務(wù)器在出項(xiàng)上導(dǎo)致第二次握手丟包。


另外,還有很多的客戶可能較關(guān)心具體的細(xì)節(jié),比如,你的首包時間是多少?首包時間是當(dāng)你發(fā)完http的get請求之后,你所拿到的第一個數(shù)據(jù)。那這第一個數(shù)據(jù)往往是你的響應(yīng)頭。這個響應(yīng)頭有可能是和你的內(nèi)容一起發(fā)送過來的,也有可能是先發(fā)送一個響應(yīng)頭然后再發(fā)內(nèi)容,這取決于你自己的server的時限。在TCP里面有一個Nagel算法,Nagel算法會把這個數(shù)據(jù)拼湊成一個大塊兒后發(fā)出。如果你要是在engikers里配TCP nodelay,把這個配完后就可以。有什么發(fā)什么可以去提升這個首包的效果。


平滑發(fā)包剛才也講過了,丟包預(yù)判就是你通過統(tǒng)計學(xué)的一些方法,把端到端的,比如,c到你的傳輸具體情況做一個記錄。然后,如果你要是發(fā)現(xiàn)丟包率是比較符合規(guī)律的話,可以在沒有丟包的時候你預(yù)判有可能丟包,那你就時不時的去把某些數(shù)據(jù)包重發(fā)一遍,發(fā)兩遍,即使他能收到。這樣的話也是可以達(dá)到加速的抗丟包效果的。


后面還有很多細(xì)節(jié),這里就不再贅述。右邊是一個linux下的TCP協(xié)議棧狀態(tài)機(jī)的切換躍遷圖。這個圖里面的open狀態(tài)指的是在沒有任何丟包的正常狀態(tài),Recovery狀態(tài)是開始有重傳。Disorder這個狀態(tài)是看到有數(shù)據(jù)包亂序。CWR是一種TCP頭部攜帶的顯性的擁塞控制,這個一般很少用到.但是蘋果操作系統(tǒng)確實(shí)支持的。左邊那個Loss狀態(tài)就是之前我一直講的一旦遇到RTO以后,就會驟降這種情況。所以,在TPC優(yōu)化的時還需考慮你怎么樣去優(yōu)化你的協(xié)議的狀態(tài)躍遷,讓他盡量不跑到Loss這個狀態(tài)。

很多做TCP優(yōu)化的,只是改變TCP擁塞控制算法,直接編譯出一個內(nèi)核模塊重新加載,然后改一下的擁塞控制模塊,再重新加載一下就OK了。實(shí)際上,這種做法只能改變你計算CWND的數(shù)量,但并不能改變他的狀態(tài)。如果你想做TCP優(yōu)化,你必須要動TCP協(xié)議棧本身。



在linux協(xié)議棧里面有一個控制參數(shù)叫tcp slow start after idle。意思是,你在數(shù)據(jù)傳輸?shù)臅r,如果等了一段時間超出一定的時間閾值之后他會把CWND給你降到初始值。


那么,這種情況是有問題的,假如你是一個http的業(yè)務(wù),而且都是這種小文件。恰好你又用了keep life這種狀態(tài),每一個請求結(jié)束后并不馬上斷掉鏈接,而是期待下一次的數(shù)據(jù)請求。在第一個數(shù)據(jù)塊object,比如下載第一個圖片,他去請求時,這個CWND會逐漸通過慢系統(tǒng)長到一定的高度。由于你兩次get請求之間可能間隔了一段時間,這個時間一旦超過閾值,就會在發(fā)送端自己把這個CWND降到初始值。一旦降到初始值,這個時候你第一個object在下載以后,CWND好不容易漲上去的就白長了。你在下載第二個的時候?qū)嶋H上還是從慢速開始。


在linux系統(tǒng)里默認(rèn)這個值開啟,它實(shí)際上是會給你降的。如果你想做優(yōu)化的話,最簡單的做法就是把它置成0。如果置成0,即使連接中間隔的時間很長,你在請求第二個object的時,他的初始的發(fā)送速度就繼續(xù)按照剛才的大小繼續(xù)發(fā)送。這樣,就可以達(dá)到一個很好的加速效果。



通過第一部分的講解,大家也知道CDN有一個非常重要的就是緩存系統(tǒng),用來做數(shù)據(jù)的緩存。當(dāng)你下載一個電影或mp3的時,數(shù)據(jù)會留在你的緩存系統(tǒng)里面。如果有第二個人還訪問同一個文件的時,還恰好通過你去訪問,那你就可以直接把這個內(nèi)容給客戶,而無需把這個內(nèi)容遞交到真正的原始服務(wù)器,然后再從原始服務(wù)器去拿。


但在真正的業(yè)務(wù)場景里,除了可緩存的內(nèi)容以外,還有一種是完全不可緩存的。比如說你的登陸、再比如說你瀏覽論壇頁面的時候有一些動態(tài)的一些元素,因?yàn)槊總€人看到的東西是不一樣的,不同的URL、不同的cookie可能看到的東西玩是完全不同,那這個時候這個數(shù)據(jù)就沒有辦法緩存。有人會說這種情況下是不是CDN就沒有價值了,如果是純動態(tài)頁面的話,其實(shí)不是的。通過架構(gòu)優(yōu)化我可以給你展示一下,通過CDN你能怎么樣去加速,能加到一個什么樣的速度?


這是個在沒有做CDN之前,客戶訪問源站的時候的連接示意圖。這里面提到一個概念RTT,之前也說到了它的真正術(shù)語是往返時延,實(shí)際上就是我們平時說的ping值。但是ping值只是RTT的一部分,并不是說RTT就是ping值。實(shí)際上,TCP也有往返時延的,比如,你發(fā)起一個信包,然后對方回復(fù),這段時間間隔也是RTT。有一種ping叫TCPping,利用的就是這個特點(diǎn)。如圖,假設(shè)客戶到原站的RTT是80毫秒,假設(shè)你要下載的文件是30kb,算一下他大概需要多久時間可以下載完成。


圖里共3種顏色,紅色代表TCP的三次握手是一個建連的過程。第一次,第二次第三次然后建連完成。大家仔細(xì)看綠色的,綠色是發(fā)get請求的時候的一個數(shù)據(jù)包。藍(lán)色的大量的數(shù)據(jù)傳輸表示服務(wù)器開始以不同周期開始吐數(shù)據(jù)。那么這里邊我是假設(shè)他初始CWND是2,那就是2、4、8這樣去長。


在TCP里邊還有一個MSS的概念,TCP協(xié)議能一個數(shù)據(jù)包存儲的最大真正的七層內(nèi)容是有多長。在普通的網(wǎng)絡(luò)當(dāng)中,MTU如果是1500字節(jié)的話,IP頭是20字節(jié),TCP頭是20字節(jié),在一般情況下MSS是1460,也就是說一個數(shù)據(jù)包可以傳遞1460字節(jié)的內(nèi)容。那我們算一下,30kb是30*1024這么多字節(jié),那么它需要幾輪才能傳輸完成呢?


第一輪發(fā)兩個數(shù)據(jù)包,第二輪發(fā)四個數(shù)據(jù)包,第三輪發(fā)八個數(shù)據(jù)包,第四輪的時候其實(shí)剩余的數(shù)據(jù)量已經(jīng)不足16個數(shù)據(jù)包了,但是仍然要發(fā)送一輪。

后面是四個來回我剛才講了,再加上前面的TCP三次握手也占一個往返時延。也就是說一共有五個來回周期。那假設(shè)這個往返時延是80毫秒,可以算一下,5*80,這是400毫秒。也就是在這么一個網(wǎng)絡(luò)的情況下,帶寬足夠充足,然后在沒有抖動也沒有丟包的情況下,要傳一個30kb的數(shù)據(jù)在80毫秒延遲的情況下,他最快的理論速度也需400毫秒才能完成,這是在CDN之前。



上圖是在做CDN之后的效果圖。我們可以看到,在客戶和園站之間,部署兩個CDN的節(jié)點(diǎn),一個叫下層一個叫上層。下層離用戶很近,這一塊兒的距離就lastmell。上層離源站近,這一塊兒這個距離我們firstmell。然后上下層之間我們叫middlemell。為確保能夠充分的體現(xiàn)即使是動態(tài)的數(shù)據(jù)我們也能起到很完美的加速效果,我在上下層之間我仍保留80毫秒。同時在Lastmell和firstmell分別引入20毫秒,那么總共延時就變成了120毫秒。也就是說現(xiàn)在網(wǎng)絡(luò)環(huán)境總延時是原來的1.5倍。


首先來看一下firstmell,因?yàn)閒irstmell和加速之前的拓普相比,唯一不同的是往返時延變小,由80毫秒變成了20毫秒。計算一下20*(1+4)=100毫秒。


再來看lastmell,由于lastmell發(fā)送端是我們自己的服務(wù)器,所以完全可以利用TCP優(yōu)化這種方式來讓數(shù)據(jù)包發(fā)送更快。比如,最簡單的加速方式就是去修改你的CWND,原來是2現(xiàn)在修改到10,目前在2.6.32內(nèi)核以上,他默認(rèn)的這個CWND應(yīng)該都是10,早期是2。谷歌在很早之前就已提出一個觀點(diǎn),早期ARFC的標(biāo)準(zhǔn)里說初始值是2,,已不合時宜,因?yàn)楝F(xiàn)在的網(wǎng)絡(luò)帶寬都很大。所以我們應(yīng)該把它提到10,后來就所有的東西都是以10為初始值。


假設(shè)初始值就是10,可以算一下需要多少個周期能把數(shù)據(jù)發(fā)完?共有30K的數(shù)據(jù),第一輪發(fā)10個,每一個數(shù)據(jù)包記住這里邊說的10個指的是10個數(shù)據(jù)包。每個數(shù)據(jù)包可存放的內(nèi)容是1460個字節(jié),那實(shí)際上第一輪發(fā)10個就已經(jīng)變成14.6k。那第二輪20個數(shù)據(jù)包用不滿就已經(jīng)發(fā)完了,套用公式20*3,實(shí)際上只需要60毫秒就可完成。


最有意思的是middlemell這塊。因?yàn)樗械臇|西全都是我們自己的,服務(wù)器也是我們自己的,然后網(wǎng)絡(luò)也是相對來說可控的。所以可以在middlemell這塊兒做很多有意思的事情。比如TCP,由于服務(wù)器是在機(jī)房,他跟原針不一樣,原針有可能帶寬很小,而在lastmell也不可能吐數(shù)據(jù)太快,如果太快你的最終客戶端的網(wǎng)絡(luò)又個瓶頸。但我們兩個節(jié)點(diǎn)之間傳輸?shù)臅r實(shí)際上是可以速度很快的,也可以直接把數(shù)據(jù)一次性的30個包傳到下層,從上層傳到下層。


除這個以外還有一個很重要的觀點(diǎn),我可以通過上下層的一種長連接的機(jī)制keeplive的一個機(jī)制,忽略TCP的3次握手。即使換不同用戶去訪問同一個下層,但因我上下層之間已經(jīng)建立了一個所謂的通道,那么也可以讓這個數(shù)據(jù)通過我這個通道直接把get請求發(fā)送到上層,上層把這個交給原針。這樣減少一個往返。套用公式可以看一下80*(0+1),總共只需要80毫秒。


把三個部分一起加起來,可以算一下60+80+100=240。也就是說,這種環(huán)境下,在總的延時是原來1.5倍的情況下,完美的做到比原來提升40%的優(yōu)化效果。在不能緩存的純動態(tài)的情況下,我在中間的middlemell沒有任何RTT減少的情況下,我的CDN架構(gòu)給你帶來的價值。


還有兩個細(xì)節(jié)我沒有說,第一個細(xì)節(jié)是,真正的我們找上下層的鏈路的時有可能會小于80毫秒。因?yàn)槔梦覀冎罢f的那個路由的最短路徑的算法,有可能會找一個經(jīng)過c點(diǎn)到達(dá)上層,總共的RTT可能會小于80毫秒或更小,實(shí)際上還能進(jìn)一步的縮短時間。另外,這里講的是上層拿到所有的數(shù)據(jù)之后才會給下層,下層拿到所有數(shù)據(jù)之后才會給用戶,實(shí)際上他不會在所有數(shù)據(jù)收到之后才傳輸,他是隨收隨傳的,所以這三個過程在時間的橫軸上是有疊加的,就導(dǎo)致時間進(jìn)一步縮短。



之前我有講,在CDN里你玩的是什么?你玩的實(shí)際上就是網(wǎng)絡(luò),尤其是對CDN公司來說。坦白來講,服務(wù)器有三大部分組成,第一部分是你的操作系統(tǒng),第二部分是你的Cache緩存系統(tǒng),第三部分就是你的網(wǎng)絡(luò)。而對于OS來說,一般你的操作系統(tǒng)選型完畢優(yōu)化之后你一般不會再動它了,除非遇到了重大的安全隱患或者是有重大的升級。而對你Cache系統(tǒng)來說也是,一般都求穩(wěn),在沒有重大的bug的時,不會去輕易的改變。但最復(fù)雜的就是網(wǎng)絡(luò),你必須要掌握對網(wǎng)絡(luò)的控制度,這樣的話你才能駕馭它。


如果你的網(wǎng)絡(luò)研究的很透徹,通過你的分析會發(fā)現(xiàn)很多問題。給各位講個案例,我們在訪問某一個資源的時,大概可能五年前或更早,我剛加入藍(lán)訊的時去分析,看到我們不如競爭對手。我通過數(shù)據(jù)包的分析發(fā)現(xiàn),不是我們資源不好,而是我們的TCP優(yōu)化沒有做,而對方做了TCP優(yōu)化。


以這個例子來講,可通過第一個信包和第二個包之間的時間差可看到他的RTT是23毫秒。通過這個RTT我們可看到它在第19個包和第21個包之間有一個時間跳變,這個跳變就意味著它屬于第二輪發(fā)包機(jī)制。那第一輪可以數(shù)一下一共是10個包,也就是說初始initcwnd值是10。假設(shè)有一個50kb的數(shù)據(jù)包需要發(fā)送,算一下需要多長時間。50*1024算出字節(jié)再除以 1460換成包數(shù),再加1,加1的原因是考慮到一定會有余數(shù),余數(shù)的話就占一個包所以加1。等于36個包,要把36個包發(fā)出去才能完成這個發(fā)送。


假如要發(fā)36個包,初始發(fā)包數(shù)量是10??伤阆?6拆解等于10+20+6。他需要3個往返才能把這個數(shù)據(jù)發(fā)完。套公式算下它的發(fā)送時間需要多久?RTT我們之前算了是23,23*4。為什么是4呢,因?yàn)槟氵€要加一個TCP三次握手的一個時間,一共需要92毫秒才能完成。



上圖是競爭對手的情況,我們可以通過第一次和第二次握手,看到他的往返時延是35毫秒。和之前的23毫秒相比,可知這個資源的ping值比原來增加了52%。通過剛才的分析方法我們也可以找到第35和37號包的跳變點(diǎn)。那么35號包之前是第一個發(fā)送輪回。整個的發(fā)包數(shù)量是20,它的初始發(fā)包數(shù)量實(shí)際上并不是標(biāo)準(zhǔn)的10,而是20。那么,我們可以再算一下,如果你有50kb必須要發(fā)出,你最終需要也是36個包,但是你初始是20就需兩輪,分別是20+16。

通過套公式,可知需要150毫秒完成。那150毫秒跟之前的92比只慢14%。在資源落后52%的情況下,最終效果才慢了14%,中間的這個差距實(shí)際上就是你的技術(shù)帶來的價值。



這是個視頻點(diǎn)播對比數(shù)據(jù)圖,高低代表發(fā)送速率,橫軸是時間。通過對比,明顯可看到廠商a的發(fā)送速度高于廠商b。做完TCP后和做TCP優(yōu)化前,差距還是很大。整個過程可看到第一個廠商的速度起來以后非常平穩(wěn),直到結(jié)束,而第二個廠商他最開始速度很快逐漸發(fā)現(xiàn)要丟包減速,速度就就漲不起來了。這就是提速優(yōu)化價值。



上圖是當(dāng)時分析為什么服務(wù)器發(fā)送慢的一個結(jié)果,通過這個分析直接就給大家總結(jié)一下吧!結(jié)果可以看到這是由于TCP算法自身的問題而導(dǎo)致的,他把時間白白浪費(fèi)了,他們有時間其實(shí)是可以繼續(xù)發(fā)出去的但并沒有繼續(xù)發(fā)。



另外,還有一個有意思的,每個廠商無論你是做CDN,做電商、做IT企業(yè),只要你有對外提供的server,而且server的負(fù)載比較高都會遇到的一個syncookie的坑。給大家講一下。在TCP的標(biāo)準(zhǔn)里有兩個選項(xiàng)一個叫WScale一個是SACK。他并不是在RFC793里邊出現(xiàn)的,他是在RFC1323里補(bǔ)充而出現(xiàn)的。


現(xiàn)在講一下這個WScale什么東西。默認(rèn)的情況下在標(biāo)準(zhǔn)的TCP協(xié)議,在早期的時候是沒有WScale概念的。他在TCP的頭部有一個16byte的空間來表示你能發(fā)送的最大字節(jié)數(shù),一個周期能發(fā)送的最大字節(jié)數(shù)。那根據(jù)TCP的吞吐量的計算公式,吞吐量一定是小于等于最大發(fā)送窗口除以RTT的,這個RTT是以秒為單位。


之所以說小于等于是因?yàn)橐话愕那闆r下他是有可能有亂序或者抖動的。假如你的TCP協(xié)議傳輸時,RTT是100毫秒,假設(shè)網(wǎng)絡(luò)之間沒有丟包也沒有亂序也沒有抖動,且?guī)捠菬o限大的。套公式可知,64k除以100毫秒,也就是0.1,吞吐量最大是640k。即使你的帶寬無限大,沒有丟包,沒有抖動,最大640k,就是這么嚴(yán)格。


大家可能覺得這個有點(diǎn)兒不可思議,為什么我們傳輸速度是遠(yuǎn)大于這個呢?因?yàn)樵谛碌臉?biāo)準(zhǔn)里引用WScale這個概念。在TCP三次握手的時候,客戶端如果要支持這個選項(xiàng)的話,服務(wù)端被通知支持這個選項(xiàng)。如果服務(wù)端也支持,會記錄下來說客戶端支持,同時回應(yīng)也支持。在客戶端拿到第二次握手時,服務(wù)端就也把自己置成支持狀態(tài)了。在數(shù)據(jù)傳輸?shù)臅r,它是以2為底數(shù),然后以WScale的這個n值為指數(shù)的一個滑動窗口遞增值。


利用這個WScale是可把發(fā)送窗口的數(shù)量漲到很大的,比如說64k、128k、256k甚至更大。如果要這樣再套公式,他的傳輸效果就會變得非常好了。



關(guān)于參數(shù)SACK,選擇性應(yīng)答,全稱是Selective ACK。在你數(shù)據(jù)傳輸?shù)臅r,沒有這個選項(xiàng)他會怎么樣呢?比如,要傳10個數(shù)據(jù)包,只有第6個數(shù)據(jù)包丟掉了,那么在服務(wù)端收到ACK的時候他會知道,只收到了5,然后就沒有其他信息了。這個時候他需要怎么做呢?需要把6到10重新發(fā)一遍。那會導(dǎo)致兩個問題,第一,你的數(shù)據(jù)從開始到傳完,速度就會變慢。第二個就是占用額外帶寬把7到10進(jìn)行一個沒必要的重傳。


同樣的在TCP三次握手的時候?qū)憳?biāo)記,并且兩邊都確認(rèn)同時開啟,如果要是都支持的話,在客戶端反饋數(shù)據(jù)的時,他就會告訴服務(wù)端,收到連續(xù)的序號完整的到5,但是我還收到了7到10。服務(wù)端就可通過這兩個信息進(jìn)行拼接找到中間的空隙,就會知道只有6號丟掉了,他就只需傳6就可以。為什么要強(qiáng)調(diào)這兩個,可能是為后面那個syncookie的坑做鋪墊。


接觸過linux的人都知道在里面有一個叫syncookie的機(jī)制。是一種幫助你去防護(hù)一定量攻擊的一種方法。那么它的原理是什么呢?在每一次數(shù)據(jù)正常建立的時它優(yōu)先消耗一個叫連接隊(duì)列的一個概念。等連接隊(duì)列滿了,如果你syncookie未開啟,有新的請求過來,他就會把那個新丟掉,如果你有大量的這種假的建連數(shù)據(jù)包已充斥滿了整個建連隊(duì)列的,那么他就會導(dǎo)致拒絕服務(wù)。


那syncookie開啟的情況下會怎么樣呢?他會在協(xié)議棧之前自己偽造一個應(yīng)答機(jī)制,并不是真正的協(xié)議棧去代應(yīng)答第二次握手。同時他的第二次握手會攜帶一個算好的一個cookie值作為第三次握手的校驗(yàn)。如果他收到了第三次握手的校驗(yàn)值的會被認(rèn)為是一個合法的建連,那么,他會把這個通過注入的方式,直接告訴你這個鏈接可以直接用了。那在前期syncookie當(dāng)滿的時候開始啟動這個狀態(tài),他是不占用隊(duì)列的,所以說他是一個非常好的防攻擊的一個手段,但是他的防攻擊的量不會很大,微量是可以的。


但坑也恰恰就在這。由于syncookie他不是標(biāo)準(zhǔn)的TCP協(xié)議棧,所以說他的支持,并不是非常的完備。等一段syncookie發(fā)出,他代應(yīng)答的第二次握手并不攜帶WScale和SACK這個選項(xiàng)。就會讓客戶端誤認(rèn)為是不支持的,所以,后續(xù)的溝通就變得非常的低效。我們之前做過一個實(shí)驗(yàn),在有一定量丟包而且大延時的情況下,你的速度可能只有300多k。后來查了很多資料發(fā)現(xiàn)確實(shí)是這個樣子,而且我們做了很多的模擬時間。比如,都為syncookie出發(fā)的時,他速度確實(shí)就很快。


后來我們做了一個改動,在syncookie上,如果要是代應(yīng)答的時,我們攜帶SACK的這個數(shù)據(jù)給客戶,那后來建連的時都可以把這個功能用起來。用起來時我們在線上是真正的無環(huán)境試驗(yàn)可以提升大概25%到35%的服務(wù)質(zhì)量。



另外,講一下關(guān)于Cache的選型。很多的公司都在自研,也有很多公司直接用的開源的軟件,至于怎么去選可能就要看你自己的場景了。比如,裸盤技術(shù)不依賴文件系統(tǒng),但他的缺點(diǎn)是在于他對業(yè)務(wù)的支撐比較差,且他是c++語言寫的COVER住的人還是不多的,那世界上有很多的公司是跟那個SD相結(jié)合,利用的方式去拆解業(yè)務(wù),后續(xù)來做Cache。

還有很多公司是走的自研路線,比如像網(wǎng)速藍(lán)汛,阿里快忙這些公司都是曾經(jīng)做過自研的,后續(xù)是什么發(fā)展目前不太清楚。



坦白來講,并不推薦自研。能用錢解決的問題都不是問題。如果去自研,第一,你要耗費(fèi)大量的人力和時間。第二,你需要去思考,你能不能cover住這些原本人家已經(jīng)做好的東西。你要自研的話,前提是你在重復(fù)造車的過程當(dāng)中一定有一個車輪,那個車輪能不能保證你的這個龍骨能夠跟人家一樣,甚至比人家更好。這里給大家分享一個我之前遇到過的自研軟件的坑。


這個數(shù)據(jù)包它體現(xiàn)的是什么?體現(xiàn)的是你看最后的那兩個數(shù)據(jù)包,倒數(shù)第二個是一個get請求。它發(fā)送完這個get請求之后馬上收到了一個RST,這個連接被斷掉了。當(dāng)時造成了很多的投訴,那我們也是去考慮這個問題到底是怎么造成的?



通過抓包在服務(wù)器上抓包微觀去分析,我們發(fā)現(xiàn)實(shí)際上這個問題是怎么造成的呢?看上面這個截圖,在客戶端發(fā)起請求的時候他有一個字段就可能是keep live。意思是說他期望去和服務(wù)器進(jìn)行這種長連接。而服務(wù)器是怎么給的呢?服務(wù)器給出去的時,并沒有明確的告訴客戶端是否支持。導(dǎo)致這個問題的原因是由于我們的研發(fā)人員并沒有真正地領(lǐng)會RTT協(xié)議的精髓,他沒有完全cover住這個RTT協(xié)議導(dǎo)致最基本的這種車輪,這個輪骨做的是有問題的導(dǎo)致很嚴(yán)重的坑。


在HTTP1.0協(xié)議里邊,如果你要是發(fā)一個可能是keeplive你希望和server進(jìn)行keeplive這種溝通的話。Server端必須要告訴說我支持這樣才能支持,有點(diǎn)像TCP的三次握手,那個WScale和那個SACK類似這樣,但是在1.1協(xié)議里邊兒恰恰不是這個樣子的。如果你的身邊沒有任何反饋的話,客戶端會默認(rèn)為,我發(fā)了這個東西,你有沒有告訴我說你不支持,那能不能支持?那這個時候問題就出現(xiàn)了。

這個就導(dǎo)致了第一個請求結(jié)束之后,服務(wù)端實(shí)際上是不支持,但沒有給出明確的顯性的信息來告訴客戶端。研發(fā)人員把1.0和1.1協(xié)議弄混了,或是他還認(rèn)為1.1協(xié)議是跟1.0一樣的標(biāo)準(zhǔn)。這個時候,在發(fā)送的第一個數(shù)據(jù)之后就把這個連接關(guān)掉,此時客戶端并不知道服務(wù)端是不支持的,他還嘗試發(fā)起第二次請求結(jié)果就導(dǎo)致被塞。


注:由于文章篇幅有限,上期所以提問問題,與下期一塊整理發(fā)布。


下期預(yù)告

第3篇:

隕坑篇—DNS 的坑、IP 庫的坑、網(wǎng)絡(luò)探測的坑、關(guān)于劫持。

報名方式,請關(guān)注下方海報:

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国内欲色一区二区三区| 成人你懂的在线免费视频| 婷婷基地五月激情五月| 久草精品视频精品视频精品| 日本91在线观看视频| 国产女同精品一区二区| 日韩精品免费一区三区| 欧美日韩三区在线观看| 亚洲国产91精品视频| 欧美同性视频免费观看| 欧美日韩免费观看视频| 91久久精品在这里色伊人| 日韩一级欧美一级久久| 精品视频一区二区不卡| 欧美日韩国产自拍亚洲| 亚洲av日韩一区二区三区四区| 男女一进一出午夜视频| 日韩欧美一区二区黄色| 欧美精品久久99九九| 少妇视频一区二区三区| 亚洲天堂久久精品成人| 欧洲日本亚洲一区二区| 国产精品不卡免费视频| 我的性感妹妹在线观看| 成人午夜激情在线免费观看| 亚洲专区一区中文字幕| 儿媳妇的诱惑中文字幕| 日韩欧美中文字幕人妻| 国产一区二区三区色噜噜| 少妇人妻精品一区二区三区 | 男人和女人干逼的视频| 麻豆亚州无矿码专区视频| 精品人妻一区二区三区四在线| 福利在线午夜绝顶三级| 日韩高清中文字幕亚洲| 亚洲av专区在线观看| 熟女高潮一区二区三区| 欧美日韩中黄片免费看| 亚洲精品一区二区三区日韩| 91精品视频全国免费| 最好看的人妻中文字幕|