Http/2 對比Http/1.1 的性能提升

2023.09.08

Http/2 對比Http/1.1 的性能提升


HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重複的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。
  • HTTP/1.1發明以來發生了哪些變化?
  • HTTP/1.1 協議的性能缺陷
  • HTTP/2 新特性
  • HTTP/2 還存在的問題

HTTP/1.1發明以來發生了哪些變化?

近年來,仔細觀察那些最流行的網站首頁所需要下載的資源的話,會發現一個非常明顯的趨勢:

  • 消息變大:從幾KB 大小的消息,到幾MB 大小的消息;
  • 頁面資源變多:從每個頁面不到10 個的資源,到每頁超100 多個資源;
  • 內容形式變多樣:從單純到文本內容,到圖片、視頻、音頻等內容;
  • 實時性要求變高:對頁面的實時性要求的應用越來越多;

自從1997 年HTTP/1.1 發布以來,我們已經使用HTTP/1.x 相當長一段時間了,但近幾年內容的爆炸式成長使得HTTP/1.1 越來越無法滿足現代網絡的需求了

HTTP/1.1 協議的性能缺陷

  • 高延遲:頁面訪問速度下降
  • 無狀態:頭部巨大切重複
  • 隊頭阻塞問題,同一連接只能在完成一個HTTP 事務(請求和響應)後,才能處理下一個事務;
  • 明文傳輸:不安全
  • 不支持服務器推送消息,因此當客戶端需要獲取通知時,只能通過定時器不斷地拉取消息,這無疑浪費大量了帶寬和服務器資源。

Http /2 的新特性

兼容HTTP/1.1

HTTP/2 出來的目的是為了改善HTTP 的性能。協議升級有一個很重要的地方,就是要兼容老版本的協議,否則新協議推廣起來就相當困難,HTTP/2 是怎麼做的呢?

HTTP/2 沒有在URI 裡引入新的協議名,仍然用「http://」表示明文協議,用「https://」表示加密協議,於是只需要瀏覽器和服務器在背後自動升級協議,這樣可以讓用戶意識不到協議的升級,很好的實現了協議的平滑升級。

還是基於TCP 協議傳輸,應用層方面為了保持功能上的兼容,與HTTP/1.1 完全一致,比如請求方法、狀態碼、頭字段等規則保留不變。

二進制傳輸

HTTP/2 不再像HTTP/1.1 裡的純文本形式的報文,而是全面採用了二進制格式,頭信息和數據體都是二進制,並且統稱為幀(frame):頭信息幀(Headers Frame)和數據幀(Data Frame)。

這樣對計算機非常友好,因為計算機收到報文後,無需再將明文的報文轉成二進制,而是直接解析二進制報文,這增加了數據傳輸的效率。

Header 壓縮(HPACK)

HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重複的,比如Cookie和User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。

HTTP/2 對這一點做了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用gzip或compress壓縮後再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以後就不發送同樣字段了,只發送索引號,這樣就提高速度了。

HPACK 算法:在客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以後就不發送同樣字段了,只發送索引號,這樣就提高速度了。

多路復用

多路復用,就是在一個TCP 連接中可以存在多條流。換句話說,也就是可以發送多個請求,對端可以通過幀中的標識知道屬於哪個請求。

這一特性使得HTTP 傳輸性能得到極大提升,主要體現在以下三個方面:

復用TCP 連接

HTTP/2 復用TCP 連接,在一個連接裡,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"

數據流

HTTP/2 並行交錯地發送多個請求/ 響應,請求/ 響應之間互不影響

HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流(stream)。每個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流ID,用來區分它屬於哪個數據流。另外還規定,客戶端發出的數據流,ID一律為奇數,服務器發出的,ID為偶數。

數據流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證TCP連接還打開著,可以被其他請求使用。

優先級

HTTP/2 還可以對每個Stream 設置不同優先級,幀頭中的「標誌位」可以設置優先級,比如客戶端訪問HTML/CSS 和圖片資源時,希望服務器先傳遞HTML/CSS,再傳圖片,那麼就可以通過設置Stream 的優先級來實現,以此提高用戶體驗。

服務端Push

HTTP/1.1 不支持服務器主動推送資源給客戶端,都是由客戶端向服務器發起請求後,才能獲取到服務器響應的資源。

比如,客戶端通過HTTP/1.1 請求從服務器那獲取到了HTML 文件,而HTML 可能還需要依賴CSS 來渲染頁面,這時客戶端還要再發起獲取CSS 文件的請求,需要兩次消息往返,如下圖左邊部分:

如上圖右邊部分,在HTTP/2 中,客戶端在訪問HTML 時,服務器可以直接主動推送CSS 文件,減少了消息傳遞的次數。

提高安全性

出於兼容的考慮,HTTP/2 延續了HTTP/1 的“明文”特點,可以像以前一樣使用明文傳輸數據,不強制使用加密通信,但HTTPS 已經是大勢所趨,各大主流瀏覽器都支持加密的HTTP/2,所以,真實應用中的HTTP/2 是還是加密的:

HTTP/2 遺留問題

HTTP/2 還會隊頭阻塞

HTTP/2 通過Stream 的並發能力,解決了HTTP/1 隊頭阻塞的問題,看似很完美了,但是HTTP/2 還是存在“隊頭阻塞”的問題,只不過問題不是在HTTP 這一層面,而是在TCP 這一層。

如果造成隊頭阻塞,問題可能比http1.1還嚴重,因為只有一個tcp連接,後續的傳輸都要等前面,http/1.1 多個tcp連接,阻塞一個,其他的還可以正常跑。