02 網(wǎng)絡(luò)面經(jīng):一個TCP連接可以發(fā)送多少個HTTP請求?
一個TCP連接可以發(fā)送多少個HTTP請求?就這這個問題,我們聊聊TCP、HTTP以及瀏覽器之間的關(guān)系和對請求處理的優(yōu)化。
TCP與HTTP的淵源
我們知道TCP協(xié)議對應(yīng)于傳輸層,HTTP協(xié)議對應(yīng)于應(yīng)用層。WEB項目中,HTTP協(xié)議是建立在TCP的基礎(chǔ)上的。
最初瀏覽器從服務(wù)器加載一個網(wǎng)頁,會發(fā)起一個HTTP請求,這時需要先建立一個TCP連接。當(dāng)本次數(shù)據(jù)請求完畢之后,會立刻斷開TCP連接。
但隨著時間的推理,HTML網(wǎng)頁內(nèi)容越來越復(fù)雜,不僅有內(nèi)容,還有JS、CSS和圖片資源,每個資源的請求都建立一次TCP連接,效率就會很低。
這時,Keep-Alive就被提出用來了,專門用于解決效率低的問題。
本文關(guān)于TCP連接能夠發(fā)送多少個HTTP請求,本質(zhì)上就是圍繞著解決通信的低效問題的。
下面我們通過幾個常見的面試問題,來逐步揭開這其中包含的知識點。
問題一:瀏覽器建立TCP連接之后,完成一次HTTP請求,是否會斷開?
HTTP協(xié)議Header中的Connection屬性決定了連接是否持久,不同HTTP協(xié)議版本有所不同。
HTTP/1.0中Connection默認為close,即每次請求都會重新建立和斷開TCP連接。缺點:建立和斷開TCP連接,代價過大。
HTTP/1.1中Connection默認為keep-alive,即連接可以復(fù)用,不用每次都重新建立和斷開TCP連接。超時之后沒有連接則主動斷開??梢酝ㄟ^聲明Connection為close進行關(guān)閉。
優(yōu)點:TCP連接可被重復(fù)利用,減少建立連接的損耗,SSL的開銷也可以避免。刷新頁面時也可以復(fù)用,從而不再建立SSL連接等。
結(jié)論:默認情況下(HTTP/1.1)建立TCP連接不會斷開,只有在請求報頭中聲明Connection: close才會請求完成之后關(guān)閉連接。不斷開的最終目的是減少建立連接所導(dǎo)致的性能損耗。
問題二:一個TCP連接可以對應(yīng)幾個HTTP請求?
如果Connection為close,則一個TCP連接只對應(yīng)一個HTTP請求。
如果Connection為Keep-alive,則一個TCP連接可對應(yīng)一個到多個HTTP請求。
問題三:一個TCP連接中,可以同時發(fā)送多個HTTP請求嗎?
HTTP/1.1中單個TCP連接在同一時刻只能處理一個請求。HTTP/1.1在RFC 2616中規(guī)定了Pipelining來解決這個問題,但瀏覽器默認是關(guān)閉的。
RFC 2616中規(guī)定:一個支持持久連接的客戶端可以在一個連接中發(fā)送多個請求(不需要等待任意請求的響應(yīng))。收到請求的服務(wù)器必須按照請求收到的順序發(fā)送響應(yīng)。
Pipelining本身存在一些問題,比如代理服務(wù)器不能正確處理HTTP Pipelining、Head-of-line Blocking連接頭阻塞(首個請求耗時過長,阻塞其他請求)。所以,瀏覽器默認關(guān)閉該功能。
HTTP/2.0提供了多路復(fù)用技術(shù)Multiplexing,一個TCP可以并發(fā)多個HTTP請求(理論無上限,但是一般瀏覽器會有TCP并發(fā)數(shù)的限制)。
HTTP/1.1中為了提升性能,通常會采用連接復(fù)用和同時建立多個TCP連接的方式提升性能。
結(jié)論:HTTP/1.1中存在Pipelining技術(shù)支持一個連接發(fā)送多個請求,但存在弊端,瀏覽器默認關(guān)閉。HTTP/2.0中通過多路復(fù)用技術(shù)支持一個TCP連接中并發(fā)請求HTTP。
問題四:瀏覽器對同一Host建立TCP連接的數(shù)量有沒限制?
不同瀏覽器限制不同,比如Chrome最多允許同一個Host可建立6個TCP連接。
如果服務(wù)器只支持HTTP/1.1,瀏覽器會采用在同一個Host下建立多個TCP連接來進行效率提升。如果是基于HTTPS傳輸,在SSL握手之后,還會嘗試協(xié)商是否可以采用HTTP/2.0的Multiplexing功能。
問題五:keep-alive使用場景及優(yōu)缺點
開啟keep-alive對內(nèi)存要求高,關(guān)閉keep-alive對CPU要求高;如果內(nèi)存和CPU都足夠,開啟和關(guān)閉keep-alive對性能影響不大;如果考慮服務(wù)器壓力,如果是靜態(tài)頁面,大量的調(diào)用js或者圖片的話,建議開啟keep-alive;如果是動態(tài)網(wǎng)頁,建議關(guān)閉keep-alive。
注意事項:如果需要使用keep-alive功能,服務(wù)器端如果使用nginx中keepalive_timeout值要大于0。
小結(jié)
通過上面的整體分析,我們不僅了解了TCP與HTTP之間的關(guān)系,還明確了現(xiàn)代瀏覽器基于不同的HTTP協(xié)議所作出的網(wǎng)絡(luò)層面優(yōu)化。而HTTP2/0的多路復(fù)用機制還是一些高性能框架的基礎(chǔ),比如gRPC的實現(xiàn)。
往期推薦
如果你覺得這篇文章不錯,那么,下篇通常會更好。添加微信好友,可備注“加群”(微信號:zhuan2quan)。
和花一輩子都看不清的人,
注定是截然不同的搬磚生涯。



