天天看點

Http 連接配接複用

0、

在真正試圖解決你的疑問的之前,我們來看一下,從發出request之前到接收respon之後,都發生了什麼。

0.你向浏覽器的位址欄輸入一個域名.如 http://www.zhihu.com

1.浏覽器向你的本地DNS伺服器請求解析該域名,即将你的http://www.zhihu.com 解析為真實的IP位址.詳細協定請查詢RFC文檔,其中對DNS協定的格式内容,指令意義,壓縮算法,等都作出了規定。

2.拿到ip位址之後,發起TCP 握手(3次),詳情請看計算機網絡TCP協定部分

3.握手成功,構造request,即 HTTP 中request請求.并發送到目的地。有關HTTP協定的内容請查閱RFC文檔可以購買HTTP權威指南作為參考和釋疑.

4.伺服器接受到一個完整的request(該邊界的指定一般是conten-length,chunked也有),根據使用者的request内容運算出相應的response。

5.伺服器将response 沿着request建立的連接配接,向浏覽器(用戶端)發送資料。

5.5 keepalive的時候不關閉該連接配接,沒有keepalive的時候發起tcp close,4次握手

6.浏覽器根據接收到的response開始渲染頁面。

至此,一個網頁的打開過程完畢,我們從中提取出耗時的部分。

1.DNS查詢時間(一來一回,走UDP協定) 網絡IO

2.tcp 建立連接配接握手 網絡IO

3.request構造時間(cpu運算)

4.request發送完畢時間(網絡IO)

5.伺服器接收request運算構造response(CPU運算,特指構造response過程中沒有任何IO操作)

6.伺服器發送response到用戶端的時間(網絡IO)

6.5 伺服器關閉連接配接時間(IO)

7.用戶端接收資料渲染頁面時間(cpu運算)。

至此,一個流程就這樣簡單地構造完畢了

1、http 1.0:每一個http請求都會打開一個tcp socket連接配接,當互動完畢後會關閉這個連接配接。之後, 從1996年開始,很多HTTP/1.0浏覽器與伺服器都對協定進行了擴充,那就是“keep-alive”擴充協定。使用HTTP/1.0的用戶端在首部中加上"Connection:Keep-Alive",請求服務端将一條連接配接保持在打開狀态。服務端如果願意将這條連接配接保持在打開狀态,就會在響應中包含同樣的首部。如果響應中沒有包含"Connection:Keep-Alive"首部,則用戶端會認為服務端不支援keep-alive,會在發送完響應封包之後關閉掉目前連接配接。

對于http 1.0,具有一些性能上的缺陷。

例如,一個包含有許多圖像的網頁檔案中并沒有包含真正的圖像資料内容,而隻是指明了這些圖像的URL位址,當WEB浏覽器通路這個網頁檔案時,浏覽器首先要發出針對該網頁檔案的請求,當浏覽器解析WEB伺服器傳回的該網頁文檔中的HTML内容時,發現其中的圖像标簽後,浏覽器将根據标簽中的src屬性所指定的URL位址再次向伺服器發出下載下傳圖像資料的請求。顯 然,通路一個包含有許多圖像的網頁檔案的整個過程包含了多次請求和響應,每次請求和響應都需要建立一個單獨的連接配接,每次連接配接隻是傳輸一個文檔和圖像,上一次和下一次請求完全分離。即使圖像檔案都很小,但是用戶端和伺服器端每次建立和關閉連接配接卻是一個相對比較費時的過程,并且會嚴重影響客戶機和伺服器的性能。當一個網頁檔案中包含JavaScript檔案,CSS檔案等内容時,也會出現類似上述的情況。

同時,帶寬和延遲也是影響一個網絡請求的重要因素。在網絡基礎建設已經使得帶寬得到極大的提升的當下,大部分時候都是延遲在于響應速度。基于此會發現,http1.0被抱怨最多的就是連接配接無法複用,和head of line blocking這兩個問題。了解這兩個問題有一個十分重要的前提:用戶端是依據域名來向伺服器建立連接配接,一般PC端浏覽器會針對單個域名的server同時建立6~8個連接配接,手機端的連接配接數則一般控制在4~6個。顯然連接配接數并不是越多越好,資源開銷和整體延遲都會随之增大。連接配接無法複用會導緻每次請求都經曆三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對檔案類大請求影響較大。head of line blocking會導緻帶寬無法被充分利用,以及後續健康請求被阻塞。

2、http 1.1:HTTP/1.1采取持久連接配接的方式替代了Keep-Alive。HTTP/1.1的連接配接預設情況下都是持久連接配接。如果要顯式關閉,需要在封包中加上Connection:Close首部。即在HTTP/1.1中,所有的連接配接都進行了複用。然而如同Keep-Alive一樣,空閑的持久連接配接也可以随時被用戶端與服務端關閉。不發送Connection:Close不意味着伺服器承諾連接配接永遠保持打開。HttpClient通過連接配接池來管理持久連接配接。

HTTP/1.1的KeepAlive就是串行的會話模式,一去一回,省掉的是TCP層面重複建立的成本。

在一個TCP連接配接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接配接的消耗和延遲。一個包含有許多圖像的網頁檔案的多個請求和應答可以在一個連接配接中傳輸,但每個單獨的網頁檔案的請求和應答仍然需要使用各自的連接配接。HTTP 1.1還允許用戶端不用等待上一次請求結果傳回,就可以發出下一次請求,但伺服器端必須按照接收到用戶端請求的先後順序依次回送響應結果,以保證用戶端能夠區分出每次請求的響應内容,這樣也顯著地減少了整個下載下傳過程所需要的時間。

3、多路複用代替原來的序列和阻塞機制,所有就是請求的都是通過一個 TCP 連接配接并發完成。

在 HTTP/2 中,有了二進制分幀之後,HTTP/2 不再依賴 TCP 連結去實作多流并行了,在 HTTP/2 中:

同域名下所有通信都在單個連接配接上完成,同個域名隻需要占用一個 TCP 連接配接,使用一個連接配接并行發送多個請求和響應。

單個連接配接可以承載任意數量的雙向資料流,單個連接配接上可以并行交錯的請求和響應,之間互不幹擾。

資料流以消息的形式發送,而消息又由一個或多個幀組成,多個幀之間可以亂序發送,因為根據幀首部的流辨別可以重新組裝。每個請求都可以帶一個 31bit 的優先值,0 表示最高優先級, 數值越大優先級越低。

4、差別的原因:

原因是因為HTTP1.1 及更低版本的協定,并沒有一個字段用來區分一個response是歸屬于哪一個request的。但HTTP 2 就有這個字段了。是以在HTTP1.1 及更低版本,你隻能在發送一個request之後,等待response的到來。HTTP1.1 request和response 的無辨別符問題(即response無法指明是哪一個request的),就造就了現在這種情況。HTTP 2 協定解除了這個問題。

繼續閱讀