一個(gè) TCP 連接可以發(fā)多少個(gè) HTTP 請(qǐng)求熊尉?

曾經(jīng)有這么一道經(jīng)典面試題:從 URL 在瀏覽器被被輸入到頁面展現(xiàn)的過程中發(fā)生了什么季稳?

相信大多數(shù)準(zhǔn)備過的同學(xué)都能回答出來馋嗜,但是如果繼續(xù)問:收到的 HTML 如果包含幾十個(gè)圖片標(biāo)簽麸俘,這些圖片是以什么方式辩稽、什么順序、建立了多少連接从媚、使用什么協(xié)議被下載下來的呢逞泄?

image

要搞懂這個(gè)問題,我們需要先解決下面五個(gè)問題:

現(xiàn)代瀏覽器在與服務(wù)器建立了一個(gè) TCP 連接后是否會(huì)在一個(gè) HTTP 請(qǐng)求完成后斷開拜效?什么情況下會(huì)斷開喷众?

一個(gè) TCP 連接可以對(duì)應(yīng)幾個(gè) HTTP 請(qǐng)求?

一個(gè) TCP 連接中 HTTP 請(qǐng)求發(fā)送可以一起發(fā)送么(比如一起發(fā)三個(gè)請(qǐng)求紧憾,再三個(gè)響應(yīng)一起接收)到千?

為什么有的時(shí)候刷新頁面不需要重新建立 SSL 連接?

瀏覽器對(duì)同一 Host 建立 TCP 連接到數(shù)量有沒有限制赴穗?

第一個(gè)問題

現(xiàn)代瀏覽器在與服務(wù)器建立了一個(gè) TCP 連接后是否會(huì)在一個(gè) HTTP 請(qǐng)求完成后斷開憔四?什么情況下會(huì)斷開?

在 HTTP/1.0 中般眉,一個(gè)服務(wù)器在發(fā)送完一個(gè) HTTP 響應(yīng)后了赵,會(huì)斷開 TCP 鏈接。但是這樣每次請(qǐng)求都會(huì)重新建立和斷開 TCP 連接甸赃,代價(jià)過大柿汛。所以雖然標(biāo)準(zhǔn)中沒有設(shè)定,某些服務(wù)器對(duì) Connection: keep-alive 的 Header 進(jìn)行了支持埠对。意思是說苛茂,完成這個(gè) HTTP 請(qǐng)求之后已烤,不要斷開 HTTP 請(qǐng)求使用的 TCP 連接。這樣的好處是連接可以被重新使用妓羊,之后發(fā)送 HTTP 請(qǐng)求的時(shí)候不需要重新建立 TCP 連接胯究,以及如果維持連接,那么 SSL 的開銷也可以避免躁绸,兩張圖片是我短時(shí)間內(nèi)兩次訪問 https://www.github.com 的時(shí)間統(tǒng)計(jì):

image

頭一次訪問裕循,有初始化連接和 SSL 開銷

image

初始化連接和 SSL 開銷消失了,說明使用的是同一個(gè) TCP 連接

持久連接:既然維持 TCP 連接好處這么多净刮,HTTP/1.1 就把 Connection 頭寫進(jìn)標(biāo)準(zhǔn)剥哑,并且默認(rèn)開啟持久連接,除非請(qǐng)求中寫明 Connection: close淹父,那么瀏覽器和服務(wù)器之間是會(huì)維持一段時(shí)間的 TCP 連接株婴,不會(huì)一個(gè)請(qǐng)求結(jié)束就斷掉。

所以第一個(gè)問題的答案是:默認(rèn)情況下建立 TCP 連接不會(huì)斷開暑认,只有在請(qǐng)求報(bào)頭中聲明 Connection: close 才會(huì)在請(qǐng)求完成后關(guān)閉連接困介。

第二個(gè)問題

一個(gè) TCP 連接可以對(duì)應(yīng)幾個(gè) HTTP 請(qǐng)求?

了解了第一個(gè)問題之后蘸际,其實(shí)這個(gè)問題已經(jīng)有了答案座哩,如果維持連接,一個(gè) TCP 連接是可以發(fā)送多個(gè) HTTP 請(qǐng)求的粮彤。

第三個(gè)問題

一個(gè) TCP 連接中 HTTP 請(qǐng)求發(fā)送可以一起發(fā)送么(比如一起發(fā)三個(gè)請(qǐng)求根穷,再三個(gè)響應(yīng)一起接收)?

HTTP/1.1 存在一個(gè)問題导坟,單個(gè) TCP 連接在同一時(shí)刻只能處理一個(gè)請(qǐng)求屿良,意思是說:兩個(gè)請(qǐng)求的生命周期不能重疊,任意兩個(gè) HTTP 請(qǐng)求從開始到結(jié)束的時(shí)間在同一個(gè) TCP 連接里不能重疊惫周。

雖然 HTTP/1.1 規(guī)范中規(guī)定了 Pipelining 來試圖解決這個(gè)問題管引,但是這個(gè)功能在瀏覽器中默認(rèn)是關(guān)閉的。

先來看一下 Pipelining 是什么闯两,RFC 2616 中規(guī)定了:

A client that supports persistent connections MAY "pipeline" its requests (i.e., send multiple requests without waiting for each response). A server MUST send its responses to those requests in the same order that the requests were received. 一個(gè)支持持久連接的客戶端可以在一個(gè)連接中發(fā)送多個(gè)請(qǐng)求(不需要等待任意請(qǐng)求的響應(yīng))褥伴。收到請(qǐng)求的服務(wù)器必須按照請(qǐng)求收到的順序發(fā)送響應(yīng)。

至于標(biāo)準(zhǔn)為什么這么設(shè)定漾狼,我們可以大概推測(cè)一個(gè)原因:由于 HTTP/1.1 是個(gè)文本協(xié)議重慢,同時(shí)返回的內(nèi)容也并不能區(qū)分對(duì)應(yīng)于哪個(gè)發(fā)送的請(qǐng)求,所以順序必須維持一致逊躁。比如你向服務(wù)器發(fā)送了兩個(gè)請(qǐng)求GET/query?q=A和GET/query?q=B似踱,服務(wù)器返回了兩個(gè)結(jié)果,瀏覽器是沒有辦法根據(jù)響應(yīng)結(jié)果來判斷響應(yīng)對(duì)應(yīng)于哪一個(gè)請(qǐng)求的。

Pipelining 這種設(shè)想看起來比較美好核芽,但是在實(shí)踐中會(huì)出現(xiàn)許多問題:

一些代理服務(wù)器不能正確的處理 HTTP Pipelining囚戚。

正確的流水線實(shí)現(xiàn)是復(fù)雜的。

Head-of-line Blocking 連接頭阻塞:在建立起一個(gè) TCP 連接之后轧简,假設(shè)客戶端在這個(gè)連接連續(xù)向服務(wù)器發(fā)送了幾個(gè)請(qǐng)求驰坊。按照標(biāo)準(zhǔn),服務(wù)器應(yīng)該按照收到請(qǐng)求的順序返回結(jié)果哮独,假設(shè)服務(wù)器在處理首個(gè)請(qǐng)求時(shí)花費(fèi)了大量時(shí)間拳芙,那么后面所有的請(qǐng)求都需要等著首個(gè)請(qǐng)求結(jié)束才能響應(yīng)。

所以現(xiàn)代瀏覽器默認(rèn)是不開啟 HTTP Pipelining 的皮璧。

但是舟扎,HTTP2 提供了 Multiplexing 多路傳輸特性,可以在一個(gè) TCP 連接中同時(shí)完成多個(gè) HTTP 請(qǐng)求悴务。至于 Multiplexing 具體怎么實(shí)現(xiàn)的就是另一個(gè)問題了睹限。我們可以看一下使用 HTTP2 的效果。

image

綠色是發(fā)起請(qǐng)求到請(qǐng)求返回的等待時(shí)間讯檐,藍(lán)色是響應(yīng)的下載時(shí)間羡疗,可以看到都是在同一個(gè) Connection,并行完成的

所以這個(gè)問題也有了答案:在 HTTP/1.1 存在 Pipelining 技術(shù)可以完成這個(gè)多個(gè)請(qǐng)求同時(shí)發(fā)送裂垦,但是由于瀏覽器默認(rèn)關(guān)閉顺囊,所以可以認(rèn)為這是不可行的肌索。在 HTTP2 中由于 Multiplexing 特點(diǎn)的存在蕉拢,多個(gè) HTTP 請(qǐng)求可以在同一個(gè) TCP 連接中并行進(jìn)行。

那么在 HTTP/1.1 時(shí)代诚亚,瀏覽器是如何提高頁面加載效率的呢晕换?主要有下面兩點(diǎn):

維持和服務(wù)器已經(jīng)建立的 TCP 連接,在同一連接上順序處理多個(gè)請(qǐng)求站宗。

和服務(wù)器建立多個(gè) TCP 連接闸准。

第四個(gè)問題

為什么有的時(shí)候刷新頁面不需要重新建立 SSL 連接?

在第一個(gè)問題的討論中已經(jīng)有答案了梢灭,TCP 連接有的時(shí)候會(huì)被瀏覽器和服務(wù)端維持一段時(shí)間夷家。TCP 不需要重新建立,SSL 自然也會(huì)用之前的敏释。

第五個(gè)問題

瀏覽器對(duì)同一 Host 建立 TCP 連接到數(shù)量有沒有限制库快?

假設(shè)我們還處在 HTTP/1.1 時(shí)代,那個(gè)時(shí)候沒有多路傳輸钥顽,當(dāng)瀏覽器拿到一個(gè)有幾十張圖片的網(wǎng)頁該怎么辦呢义屏?肯定不能只開一個(gè) TCP 連接順序下載,那樣用戶肯定等的很難受,但是如果每個(gè)圖片都開一個(gè) TCP 連接發(fā) HTTP 請(qǐng)求闽铐,那電腦或者服務(wù)器都可能受不了蝶怔,要是有 1000 張圖片的話總不能開 1000 個(gè)TCP 連接吧,你的電腦同意 NAT 也不一定會(huì)同意兄墅。

所以答案是:有踢星。Chrome 最多允許對(duì)同一個(gè) Host 建立六個(gè) TCP 連接。不同的瀏覽器有一些區(qū)別察迟。

https://developers.google.com/web/tools/chrome-devtools/network/issues#queued-or-stalled-requestsdevelopers.google.com

那么回到最開始的問題斩狱,收到的 HTML 如果包含幾十個(gè)圖片標(biāo)簽,這些圖片是以什么方式扎瓶、什么順序所踊、建立了多少連接、使用什么協(xié)議被下載下來的呢概荷?

如果圖片都是 HTTPS 連接并且在同一個(gè)域名下秕岛,那么瀏覽器在 SSL 握手之后會(huì)和服務(wù)器商量能不能用 HTTP2,如果能的話就使用 Multiplexing 功能在這個(gè)連接上進(jìn)行多路傳輸误证。不過也未必會(huì)所有掛在這個(gè)域名的資源都會(huì)使用一個(gè) TCP 連接去獲取继薛,但是可以確定的是 Multiplexing 很可能會(huì)被用到。

如果發(fā)現(xiàn)用不了 HTTP2 呢愈捅?或者用不了 HTTPS(現(xiàn)實(shí)中的 HTTP2 都是在 HTTPS 上實(shí)現(xiàn)的遏考,所以也就是只能使用 HTTP/1.1)。那瀏覽器就會(huì)在一個(gè) HOST 上建立多個(gè) TCP 連接蓝谨,連接數(shù)量的最大限制取決于瀏覽器設(shè)置灌具,這些連接會(huì)在空閑的時(shí)候被瀏覽器用來發(fā)送新的請(qǐng)求,如果所有的連接都正在發(fā)送請(qǐng)求呢譬巫?那其他的請(qǐng)求就只能等等了咖楣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市芦昔,隨后出現(xiàn)的幾起案子诱贿,更是在濱河造成了極大的恐慌,老刑警劉巖咕缎,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珠十,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡凭豪,警方通過查閱死者的電腦和手機(jī)焙蹭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墅诡,“玉大人壳嚎,你說我怎么就攤上這事桐智。” “怎么了烟馅?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵说庭,是天一觀的道長。 經(jīng)常有香客問我郑趁,道長刊驴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任寡润,我火速辦了婚禮捆憎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梭纹。我一直安慰自己躲惰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布变抽。 她就那樣靜靜地躺著础拨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绍载。 梳的紋絲不亂的頭發(fā)上诡宗,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音击儡,去河邊找鬼。 笑死蛀柴,一個(gè)胖子當(dāng)著我的面吹牛名扛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播旺订,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼超燃,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了樱调?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤圣猎,失蹤者是張志新(化名)和其女友劉穎送悔,沒想到半個(gè)月后欠啤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屋灌,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眉撵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了落塑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片污朽。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晦款,死狀恐怖缓溅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤瞒津,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站祭务,受9級(jí)特大地震影響义锥,放射性物質(zhì)發(fā)生泄漏缨该。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧珍德,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽击孩。三九已至,卻和暖如春鹏漆,著一層夾襖步出監(jiān)牢的瞬間巩梢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工甫男, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留且改,地道東北人验烧。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓板驳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親碍拆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子若治,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345