HTTP有很多版本,每個版本也有自身的差異性, 本文是對
HTTP不同版本主要特性的一個概述和總結,希望能協助到大家。
HTTP1.0
早先1.0的HTTP版本,是一種無狀態、無串連的應用程式層協議。
HTTP1.0規定瀏覽器和伺服器保持短暫的串連,瀏覽器的每次請求都需要與伺服器建立一個TCP串連,伺服器處理完成後立即斷開TCP串連(無串連),伺服器不跟蹤每個用戶端也不記錄過去的請求(無狀態)。
這種無狀態性可以藉助cookie/session機制來做身份認證和狀態記錄。而下面兩個問題就比較麻煩了。
首先,不需連線的特性導致最大的效能缺陷就是無法複用串連。每次發送請求的時候,都需要進行一次TCP的串連,而TCP的串連釋放過程又是比較費事的。這種不需連線的特性會使得網路的利用率非常低。
其次就是就是隊頭阻塞(head of line blocking)。由於HTTP1.0規定下一個請求必須在前一個請求響應到達之前才能發送。假設前一個請求響應一直不到達,那麼下一個請求就不發送,同樣的後面的請求也給阻塞了。
為瞭解決這些問題,HTTP1.1出現了。
HTTP1.1
對於HTTP1.1,不僅繼承了HTTP1.0簡單的特點,還克服了諸多HTTP1.0效能上的問題。
首先是長串連,HTTP1.1增加了一個Connection欄位,通過設定Keep-Alive可以保持HTTP串連不斷開,避免了每次用戶端與伺服器請求都要重複建立釋放建立TCP串連,提高了網路的利用率。如果用戶端想關閉HTTP串連,可以在要求標頭中攜帶Connection: false來告知伺服器關閉請求。
其次,是HTTP1.1支援要求管道化(pipelining)。基於HTTP1.1的長串連,使得請求管線化成為可能。管線化使得請求能夠並行傳輸。舉個例子來說,假如響應的主體是一個html頁面,頁面中包含了很多img,這個時候keep-alive就起了很大的作用,能夠進行並行發送多個請求。(用戶端依據網域名稱來向伺服器建立串連,一般PC瀏覽器會針對單個網域名稱的伺服器同時建立6~8個串連,手機端一般控制在4~6個。這也是為什麼很多大型網站設定不同的靜態資源CDN網域名稱來載入資源。)
需要注意的是,伺服器必須按照用戶端請求的先後順序依次回送相應的結果,以保證用戶端能夠區分出每次請求的響應內容。
也就是說,HTTP管道化可以讓我們把先進先出隊列從用戶端(請求隊列)遷移到服務端(響應隊列)。
,用戶端同時發了兩個請求分別來擷取html和css,假如說伺服器的css資源先準備就緒,伺服器也會先發送html再發送css。
同時,管道化技術只是使得用戶端能夠往一個伺服器同時發送一組請求,假若用戶端想往這個相同的伺服器發起另一組請求,也必須等待上一組請求全部響應完畢。
可見,HTTP1.1解決隊頭阻塞(head of line blocking)還不徹底。同時“管道化”技術存在各種各樣的問題,所以很多瀏覽器要麼根本不支援它,要麼就直接預設關閉,並且開啟的條件很苛刻...
此外,HTTP1.1還加入了緩衝處理(強緩衝和協商緩衝[傳送門]),支援斷點傳輸,以及增加了Host欄位(使得一個伺服器能夠用來建立多個Web網站)。
HTTP2.0
HTTP2.0的新特性大致如下:
二進位分幀
HTTP2.0通過在應用程式層和傳輸層之間增加一個二進位分幀層,突破了HTTP1.1的效能限制、改進傳輸效能。
可見,雖然HTTP2.0的協議和HTTP1.x協議之間的規範完全不同了,但是實際上HTTP2.0並沒有改變HTTP1.x的語義。
簡單來說,HTTP2.0只是把原來HTTP1.x的header和body部分用frame重新封裝了一層而已。
多工(串連共用)
下面是幾個概念:
可見,所有的HTTP2.0通訊都在一個串連上完成,這個串連可以承載任意數量的雙向資料流。
每個資料流以訊息的形式發送,而訊息由一或多個幀組成。這些幀可以亂序發送,然後再根據每個幀首部的流標識符(stream id)重新組裝。
舉個例子,每個請求是一個資料流,資料流以訊息的方式發送,而訊息又分為多個幀,幀首部記錄著stream id用來標識所屬的資料流,不同屬的幀可以在串連中隨機混雜在一起。接收方可以根據stream id將幀再歸屬到各自不同的請求當中去。
另外,多工(串連共用)可能會導致關鍵請求被阻塞。HTTP2.0裡每個資料流都可以設定優先權和依賴,優先順序高的資料流會被伺服器優先處理和返回給用戶端,資料流還可以依賴其他的子資料流。
首部壓縮
在HTTP1.x中,首部中繼資料都是以純文字的形式發送的,通常會給每個請求增加500~800位元組的負荷。
比如說cookie,預設情況下,瀏覽器會在每次請求的時候,把cookie附在header上面發送給伺服器。(由於cookie比較大且每次都重複發送,一般不儲存資訊,只是用來做狀態記錄和身份認證)
HTTP2.0使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免了重複header的傳輸,又減小了需要傳輸的大小。高效的壓縮演算法可以很大的壓縮header,減少發送包的數量從而降低延遲。
伺服器推送
伺服器除了對最初請求的響應外,伺服器還可以額外的向用戶端推送資源,而無需用戶端明確的請求。
總結
HTTP1.0
HTTP1.1
持久串連
請求管道化
增加緩衝處理
增加Host欄位、支援斷點傳輸等
HTTP2.0
二進位分幀
多工(或串連共用)
首部壓縮
伺服器推送