還在糾結(jié)到哪里能找到“最好最快的”網(wǎng)絡(luò)提供商?最近我聽取并比較了十多個不同的方案之后,有人提醒了我一個簡單的事實(shí):業(yè)界采用的主要指標(biāo)(帶寬)實(shí)際上極具誤導(dǎo)性。其實(shí)對于大部分網(wǎng)站瀏覽的應(yīng)用來說,超過幾兆的網(wǎng)絡(luò)連接對于性能只有很小的提升。

罪魁禍?zhǔn)字痪褪?ldquo;TCP慢啟動”,對,這是個功能,不是缺陷。要理解其中的原因,我們必須到TCP棧里面一探究竟,這樣我們也能學(xué)到一些建立更快速網(wǎng)絡(luò)服務(wù)的有趣的小技巧。

TCP慢啟動

TCP協(xié)議提供了許多內(nèi)置的功能,其中我們感興趣的兩個是擁塞控制和擁塞避免。TCP慢啟動是TCP層內(nèi)部實(shí)現(xiàn)擁塞控制的一種機(jī)制。

慢啟動和其它一些算法聯(lián)合使用,避免發(fā)送過多的數(shù)據(jù)以至網(wǎng)絡(luò)無力傳輸,也就是防止網(wǎng)絡(luò)擁塞。

– wikipedia

表面上的流程很簡單:客戶端發(fā)送一個SYN包,它告知本端的最大緩存大小(rwnd – 接收窗口),發(fā)送端回傳幾個包作為應(yīng)答(cwnd-擁塞窗口),之后,每次它收到來自客戶端的ACK包,它就把發(fā)送包(傳輸中并未收到確認(rèn)的)的數(shù)量加倍。

這個過程也被稱作TCP連接的“指數(shù)增長”階段。OSI學(xué)院有一個很好的動畫演示這個過程:(滾動到底點(diǎn)擊播放)。那么,這和我們有什么關(guān)系呢?不管你的帶寬有多大,每一個TCP連接都要經(jīng)歷這個過程,這也就是說,通常情況下,實(shí)際用到的帶寬受制于發(fā)送端和接收端的緩存大小的設(shè)置。

HTTP和TCP慢啟動

或者,稍微換個說法,一個10M的帶寬平均上只用了16%的容量。老天!這說明,如果我們要提高網(wǎng)速,我們應(yīng)該著眼于降低客戶端和服務(wù)器之間的往返時延,而不一定要一味地花錢提高帶寬。當(dāng)然,當(dāng)你在緩沖一個大文件的時候高帶寬很有用,或者跑個速度測試也能唬唬人。問題是,基于HTTP的交互傾向于應(yīng)用短暫、突發(fā)的連接 – 在這樣的情況下,我們常常無法占用信道的全部容量!Google做一個研究表明,當(dāng)帶寬從5M升高到10M,頁面加載時間只提高了讓人失望的5%。

CWND的故事

如果TCP慢啟動很慢的話,我們不能讓它快一點(diǎn)么?其實(shí),直到最近,Linux TCP棧本身把擁塞窗口(cwnd)的初始值硬編碼為3到4個包,這也就是4kb的大小(一個包大約1360字節(jié))。還有個頻繁發(fā)生的問題,HTTP有每獲取一個資源要建立一個連接的毛病。這些加在一塊,你的性能就受到了嚴(yán)重限制。

在內(nèi)核2.6.33版本里,經(jīng)過了長期討論和提交很多的IETF修改建議之后,cwnd的初始值被設(shè)為10個包。這本身就是一個很大的進(jìn)步。但是有個問題,猜猜現(xiàn)在大部分服務(wù)器跑的是什么版本的內(nèi)核?沒錯,也許現(xiàn)在是時候更新你的服務(wù)器了。給你個實(shí)用的小提示,如果你考慮你的網(wǎng)絡(luò)服務(wù)開始使用 SPDY,那么如果不在最近的幾個內(nèi)核上面跑,你實(shí)際上不會得到任何的性能提升!TCP棧的一個小小的改動在全局能產(chǎn)生巨大的變化。

那么我該怎么辦?

TCP慢啟動是一個功能,不是缺陷,而且它的確包含有趣而重大的意義。作為開發(fā)者,我們經(jīng)常會忽視客戶端到服務(wù)器的往返時延,但是如果如果我們真有志于建立更快的網(wǎng)站,現(xiàn)在該去研究一下這些選擇了:在和網(wǎng)絡(luò)服務(wù)通信的時候重用TCP連接,建立支持HTTP keep-alive和流水線的網(wǎng)絡(luò)應(yīng)用,重視端到端的時延。噢,還有,別在高于10兆的寬帶上浪費(fèi)錢了,可能你根本就不需要。

分享到

zhangcun

相關(guān)推薦