<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你猜一個(gè) TCP 連接上面能發(fā)多少個(gè) HTTP 請(qǐng)求?

          共 6508字,需瀏覽 14分鐘

           ·

          2023-07-28 13:25

          原文鏈接:zhuanlan.zhihu.com/p/61423830

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

          大多數(shù)回答都是說請(qǐng)求響應(yīng)之后 DOM 怎么被構(gòu)建,被繪制出來。但是你有沒有想過,收到的 HTML 如果包含幾十個(gè)圖片標(biāo)簽,這些圖片是以什么方式、什么順序、建立了多少連接、使用什么協(xié)議被下載下來的呢?

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

          • 1.現(xiàn)代瀏覽器在與服務(wù)器建立了一個(gè) TCP 連接后是否會(huì)在一個(gè) HTTP 請(qǐng)求完成后斷開?什么情況下會(huì)斷開?
          • 2.一個(gè) TCP 連接可以對(duì)應(yīng)幾個(gè) HTTP 請(qǐng)求?
          • 3.一個(gè) TCP 連接中 HTTP 請(qǐng)求發(fā)送可以一起發(fā)送么(比如一起發(fā)三個(gè)請(qǐng)求,再三個(gè)響應(yīng)一起接收)?
          • 4.為什么有的時(shí)候刷新頁(yè)面不需要重新建立 SSL 連接?
          • 5.瀏覽器對(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ì):頭一次訪問,有初始化連接和 SSL 開銷初始化連接和 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)求的。

          具體的數(shù)量沒有固定限制,取決于多種因素,例如:

          • HTTP 版本:HTTP/1.1 支持持久連接,可以在同一個(gè) TCP 連接上發(fā)送多個(gè)請(qǐng)求和響應(yīng)。而在 HTTP/1.0 中,每次請(qǐng)求和響應(yīng)后都會(huì)關(guān)閉連接,因此每個(gè) TCP 連接只能對(duì)應(yīng)一個(gè) HTTP 請(qǐng)求。
          • 服務(wù)器配置:服務(wù)器可以配置連接超時(shí)時(shí)間、最大請(qǐng)求數(shù)量等限制來管理連接,這些限制可能會(huì)影響一個(gè) TCP 連接上的 HTTP 請(qǐng)求數(shù)量。
          • 瀏覽器實(shí)現(xiàn):不同的瀏覽器可能會(huì)對(duì)連接管理和請(qǐng)求流程實(shí)現(xiàn)不同,因此可能會(huì)在同一個(gè) TCP 連接上發(fā)送不同數(shù)量的 HTTP 請(qǐng)求。

          一般來說,現(xiàn)代瀏覽器可以在同一個(gè) TCP 連接上發(fā)送數(shù)十個(gè) HTTP 請(qǐng)求和響應(yīng),以提高性能和效率。但在某些情況下,例如服務(wù)器端的連接限制或?yàn)g覽器的策略限制,可能會(huì)限制連接上的請(qǐng)求數(shù)量。

          第三個(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 的效果。

          綠色是發(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í)代,瀏覽器是如何提高頁(yè)面加載效率的呢?主要有下面兩點(diǎn):

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

          第四個(gè)問題

          為什么有的時(shí)候刷新頁(yè)面不需要重新建立 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)頁(yè)該怎么辦呢?肯定不能只開一個(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)求就只能等等了。

          - END -

                
                   
                       
                          
           推薦閱讀 





                         
          原來懂Kubernetes,找工作這么吃香! 
          為什么我不再使用Alpine Linux?
          阿里 Nacos 高可用集群部署
          一位老架構(gòu)師的忠告:別想著靠技術(shù)生存一輩子
          神器 Nginx 的學(xué)習(xí)手冊(cè) ( 建議收藏 )
          K8S 常用資源 YAML 詳解
          DevOps與CI/CD常見面試問題匯總
          我會(huì)在Docker容器中抓包了!
          19 個(gè) K8S集群常見問題總結(jié),建議收藏
          運(yùn)維高可用架構(gòu)的 6 大常規(guī)方案
          運(yùn)維監(jiān)控指標(biāo)全方面總結(jié)
          9 個(gè)實(shí)用 Shell 腳本,建議收藏!
          詳解 K8S Helm CI/CD發(fā)布流程
          ES+Redis+MySQL,這套高可用架構(gòu)設(shè)計(jì)太頂了!
          一臺(tái)服務(wù)器最大能支持多少條TCP連接?
          K8S運(yùn)維必知必會(huì)的 Kubectl 命令總結(jié)
          16 張圖硬核講解 Kubernetes 網(wǎng)絡(luò)
          史上最全 Jenkins Pipeline流水線詳解
          主流監(jiān)控系統(tǒng) Prometheus 學(xué)習(xí)指南
                         
          搭建一套完整的企業(yè)級(jí) K8s 集群(二進(jìn)制方式)
                          
          40個(gè) Nginx 常問面試題
          Linux運(yùn)維工程師 50個(gè)常見面試題
                  
                    

                      

          點(diǎn)亮,服務(wù)器三年不宕機(jī)

          瀏覽 1538
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  快一本码道在线播放视频国产 | 成人免费电影在线观看五月天婷婷 | 成人综合中文字幕 | 日韩性做爰免费A片AA片 | 男人的天堂网V |