伯陽的網絡筆記(三):HTTP/2

由於疫情期間在外當志願者,晚上回家無聊翻翻網絡知識,權當記錄了。
初始動筆:2019-02-06
修改時間:2019-03-27
GitHub Repo:BoyangBloghtml

1. HTTP/1.x 的問題

不得不說, HTTP/1.1 是一個偉大的協議,如今仍然有很是多的網站使用它,充分說明了它的健壯、巧妙。可是,它畢竟是一個建立於互聯網時代前的協議,雖然已經頗有預見性了,可是仍然有些過期了。主要有如下幾個問題:git

  1. HTTP 只容許每一個 TCP 鏈接有一個未完成的請求,會有隊首阻塞的問題;
  2. 對於同一個域名,瀏覽器最多能夠同時建立 6~8 個 TCP 鏈接;
  3. Header 有點過大了;
  4. 爲了儘量減小請求數,須要作合併文件、減小圖像等優化工做,可是這無疑形成了單個請求內容變大延遲變高的問題;
  5. 明文傳輸。

因此,隨着求變的聲音愈來愈多,HTTP/2 應聲而出。程序員

2. SPDY

等一下,正式講到 HTTP/2 以前,咱們須要先提一下 SPDYgithub

由於遲遲沒有 HTTP/1.1 的優化出線,谷歌本身推出了一個新的網絡協議,叫作 SPDY,它的不少設計,被採用到了 HTTP/2 當中,好比說多路複用、二進制分幀、頭部壓縮、服務器推送等等。瀏覽器

3. HTTP/2 簡介

在2012年,W3C向社會徵求 HTTP/2 的建議,而後決定將 SPDY 當作制定標準的基礎。目標上, HTTP/2 致力於突破上一代協議衆所周知的性能限制,對 HTTP/1.x 進行擴展,而非替代,核心概念不會改變。下圖展現了 HTTP/1 和 HTTP/2 的區別。 緩存

它作了不少改變,下面細講。 不過在講以前,要先解釋 HTTP/2 中的幾個概念:服務器


  • 已創建的鏈接上的雙向字節流
  • 消息
    與邏輯消息對應的完整的一系列數據幀

  • HTTP/2 通訊的最小單位

全部的 HTTP/2 通訊都是在一個 TCP 鏈接上完成,這個鏈接能夠承載任意數量的雙向數據流。相應的,每一個數據流以消息的形式發送,而消息由一個或多個幀組成,這些幀能夠亂序發送,而後再根據每一個幀首部的流表示符從新組裝。cookie

二進制分幀

HTTP/2 性能加強的核心,全在於新增的二進制分幀層,它定義瞭如何封裝 HTTP 消息並在客戶端與服務器之間傳輸。 網絡

這裏的」層」,指的是位於會話層和應用層之間的一個新的機制:HTTP 的語義不受影響,不一樣的是傳輸期間對它們的編碼方式改變了。HTTP/1.x 以換行符做爲純文本的分隔符,而 HTTP/2 將全部傳輸的信息分割爲更小的消息和幀,並對他們採用了二進制格式的編碼。性能

多向請求和響應

在 HTTP/1.x 中,若是客戶端想要發送多個並行的請求以改進性能,那麼必須使用多個 TCP 鏈接;每一個鏈接每次只交付一個響應,多個響應必需要排隊。更糟糕的在於,這樣很是容易發生隊首堵塞,從而形成 TCP 鏈接效率低下。

HTTP/2 中的二進制分幀,突破了這種限制,客戶端和服務器能夠把 HTTP 消息分解爲互不依賴的幀,而後亂序發送,而後在另外一端把他們從新組合起來。以下如所示。

將 HTTP 消息分解爲獨立的幀,交錯發送,而後在另一端從新組裝是 HTTP/2 最重要的一項加強。它帶來了如下幾個優勢:

  • 能夠並行交錯的發送請求,請求之間互不影響;
  • 能夠並行交錯的發送響應,響應之間互不干擾;
  • 只使用一個鏈接便可並行發送多個請求和響應(多路複用);
  • 消除沒必要要的延遲;
  • 沒必要再繼續在爲了繞過 HTTP/1.x 的限制作不少工做;
  • ......

總之,這個技術解決了 HTTP/1.1 中存在的隊首阻塞問題,也消除了並行處理和發送請求及響應時對多個鏈接的依賴。

流量控制

在同一個 TCP 上傳輸多個數據流,就意味着要共享帶寬。標定數據流的優先級有助於按序交付,但只有優先級還不足以肯定多個數據流或多個鏈接之間的資源分配。因此,HTTP/2 提供了一個簡單的機制:

  • 流量控制基於每一跳進行,而非端到端的控制;
  • 流量控制基於窗口更新幀進行,即接收方廣播本身準備接受某個數據流的多少字節,以及對整個鏈接要接收多少字節;
  • 流量控制窗口大小經過 WINDOW_UPDATE 幀更新;

咱們能夠發現,它和 TCP 流量控制很是相似,事實上這兩個機制是同樣的。

這個由程序員手動控制。

服務器推送

服務器能夠對一個客戶端請求發送多個響應。換句話說,除了對最初請求的響應外,服務器還能夠額外向客戶端推送資源,而無需客戶端明確地請求。

由於有些資源,好比去線上閱讀說一本書,就能夠預測到下一步可能的閱讀的頁面,進而提早進行緩存。

首部壓縮

HTTP 的每一次通訊都會帶一組完整的首部,用於描述傳輸的資源及其屬性。在 HTTP/1.1 中,這些數據都是以純文本的形式發送的,一般會給每一個請求增長 500~800 字節的負荷;若是再算上 cookie ,增長的負荷可能會加大到上千字節。爲了減小這些開銷,HTTP/2 會壓縮首部數據。

HTTP/2 鏈接的兩端都知道已經發送了哪些首部,這些首部是什麼,從而能夠針對以前的數據只編碼發送差別數據。

4. 加密

雖然一直有加入 TLS 的提議,可是最後 HTTP/2 並未強制加入 TLS。只是有些網站會加上。

5. HTTP/2 和 HTTP/3

HTTP/2 依然是以 TCP 做爲基礎的,可是 TCP 依然會有三次握手消耗時間,爲了優化它,谷歌專門搞了一個基於 UDP 協議的 QUIC 協議。這個協議正在被一些大廠使用,可是由於源於 UDP 協議,有可能被運營商破壞,前景依然須要觀察。

QUIC的相關原理能夠查看科普:QUIC協議原理分析這篇文章。

總結

總的來講,HTTP/2 是基於 HTTP/1.1 進行的拓展,有效的優化了速度和數據量。在多路複用、二進制分幀、頭部壓縮、服務器推送上的優化很是的精妙和讓人陶醉。

引用

RFC7540:Hypertext Transfer Protocol Version 2 (HTTP/2)

SPDY Wiki

《Web性能權威指南》

相關文章
相關標籤/搜索