一、HTTP 2.0:改進傳輸性能
HTTP 2.0 的主要目標是改進傳輸性能,實現低延遲和高吞吐量。從另一方面看,HTTP 的高層協議語義並不會因爲這次版本升級而受影響。所有HTTP 首部、值,以及它們的使用場景都不會變。
現有的任何網站和應用,無需做任何修改都可以在HTTP 2.0 上跑起來。不用爲了利用HTTP 2.0 的好處而修改標記。HTTP 服務器必須運行HTTP 2.0 協議,但大部分用戶都不會因此而受到影響。
二、HTTP2.0歷史及其與SPDY的淵源
SPDY 是谷歌開發的一個實驗性協議,於2009 年年中發佈,主要目標是通過解決HTTP 1.1 中廣爲人知的一些性能限制,來減少網頁的加載延遲
SPDY協議設定的目標
- 頁面加載時間(PLT,Page • Load Time)降低 50%;
- 無需網站作者修改任何內容;
- 把部署複雜性降至最低,無需變更網絡基礎設施;
- 與開源社區合作開發這個新協議;
收集真實性能數據,驗證這個實驗性協議是否有效。
注:爲了達到降低50% 頁面加載時間的目標,SPDY 引入了一個新的二進制分幀數據層,以實現多向請求和響應、優先次序、最小化及消除不必要的網絡延遲,目的是更有效地利用底層TCP 連接;
HTTP-WG(HTTP Working Group)在2012 年初把HTTP 2.0提到了議事日程,吸取SPDY 的經驗教訓,並在此基礎上制定官方標準
三、HTTP2.0深入探究
HTTP/2.0 應該滿足如下條件:
- 相對於使用TCP 的HTTP 1.1,• 用戶在大多數情況下的感知延遲要有實質上、可度量的改進;
- 解決 HTTP 中的“隊首阻塞”問題;
- 並行操作無需與服務器建立多個連接,從而改進 TCP 的利用率,特別是擁塞控制方面;
- 保持 HTTP 1.1 的語義,利用現有文檔,包括(但不限於)HTTP 方法、狀態碼、URI,以及首部字段;
- 明確規定 HTTP 2.0 如何與 HTTP 1.x 互操作,特別是在中間介質上;
- 明確指出所有新的可擴展機制以及適當的擴展策略。
HTTP 2.0 致力於突破上一代標準衆所周知的性能限制,但它也是對之前1.x 標準的擴展,而非替代。之所以要遞增一個大版本到2.0,主要是因爲它改變了客戶端與服務器之間交換數據的方式,HTTP 2.0 增加了新的二進制分幀數據層
四、HTTP2.0設計和技術目標
HTTP/2.0 通過支持首部字段壓縮和在同一連接上發送多個併發消息,讓應用更有效地利用網絡資源,減少感知的延遲時間。而且,它還支持服務器到客戶端的主動推送機制。
二進制分幀層
- HTTP 2.0 二進制分幀層,封裝HTTP 消息並在客戶端與服務器之間傳輸
HTTP2.0 將所有傳輸的信息分割爲更小的消息和幀,並對它們採用二進制格式的編碼。
注:HTTPS 是二進制分幀的另一個典型示例:所有HTTP 消息都以透明的方式爲我們編碼和解碼,不必對應用進行任何修改。HTTP2.0工作原理有點類似
流、消息和幀
- 流:流是連接中的一個虛擬信道,可以承載雙向的消息;每個流都有一個唯一的整數標識符(1、2…N);
- 消息:是指邏輯上的 HTTP 消息,比如請求、響應等,由一或多個幀組成。
- 幀:HTTP 2.0 通信的最小單位,每個幀包含幀首部,至少也會標識出當前幀所屬的流,承載着特定類型的數據,如 HTTP 首部、負荷,等等
- HTTP 2.0 的所有幀都採用二進制編碼,所有首部數據都會被壓縮。
- 所有通信都在一個 TCP 連接上完成。
- HTTP 2.0 把HTTP協議通信的基本單位縮小爲一個一個的幀,這些幀對應着邏輯流中的消息。相應地,很多流可以並行地在同一個TCP 連接上交換消息
多向請求與響應
HTTP 2.0 中新的二進制分幀層突破了這些限制,實現了多向請求和響應:客戶端和服務器可以把HTTP 消息分解爲互不依賴的幀,然後亂序發送,最後再在另一端把它們重新組合起來
圖中包含了同一個連接上多個傳輸中的數據流:客戶端正在向服務器傳輸一個DATA 幀(stream 5),與此同時,服務器正向客戶端亂序發送stream 1 和stream 3的一系列幀。此時,一個連接上有3 個請求/ 響應並行交換!
把HTTP 消息分解爲獨立的幀,交錯發送,然後在另一端重新組裝是HTTP 2.0 最重要的一項增強。這個機制會在整個Web 技術棧中引發一系列連鎖反應,從而帶來巨大的性能提升。
* 可以並行交錯地發送請求,請求之間互不影響; * 可以並行交錯地發送響應,響應之間互不干擾; * 只使用一個連接即可並行發送多個請求和響應; * 消除不必要的延遲,從而減少頁面加載的時間; * 不必再爲繞過 HTTP 1.x 限制而多做很多工作;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- HTTP 2.0 的二進制分幀機制解決了HTTP 1.x 中存在的隊首阻塞問題,也消除了並行處理和發送請求及響應時對多個連接的依賴。
請求優先級
- 把HTTP 消息分解爲很多獨立的幀之後,就可以通過優化這些幀的交錯和傳輸順序,每個流都可以帶有一個31 比特的優先值:0 表示最高優先級;2的31次方-1 表示最低優先級。
- 服務器可以根據流的優先級,控制資源分配(CPU、內存、帶寬),而在響應數據準備好之後,優先將最高優先級的幀發送給客戶端。
- HTTP 2.0 一舉解決了所有這些低效的問題:瀏覽器可以在發現資源時立即分派請求,指定每個流的優先級,讓服務器決定最優的響應次序。這樣請求就不必排隊了,既節省了時間,也最大限度地利用了每個連接。
每個來源一個連接
- 有了新的分幀機制後,HTTP 2.0 不再依賴多個TCP 連接去實現多流並行了。每個數據流都拆分成很多幀,而這些幀可以交錯,還可以分別優先級。HTTP 2.0 連接都是持久化的,而且客戶端與服務器之間也只需要一個連接即可。
- 實驗表明,客戶端使用更少的連接肯定可以降低延遲時間。HTTP 2.0 發送的總分組數量比HTTP 差不多要少40%。
- 大多數HTTP 連接的時間都很短,而且是突發性的,但TCP 只在長時間連接傳輸大塊數據時效率才最高。HTTP 2.0 通過讓所有數據流共用同一個連接,可以更有效地使用TCP 連接。
- 有了新的分幀機制後,HTTP 2.0 不再依賴多個TCP 連接去實現多流並行了。每個數據流都拆分成很多幀,而這些幀可以交錯,還可以分別優先級。HTTP 2.0 連接都是持久化的,而且客戶端與服務器之間也只需要一個連接即可。
流量控制
- HTTP 2.0 爲數據流和連接的流量控制提供了一個簡單的機制:
- 流量控制基於每一跳進行,而非端到端的控制;
- 流量控制基於窗口更新幀進行,即接收方廣播自己準備接收某個數據流的多少字節,以及對整個連接要接收多少字節;
- 流量控制窗口大小通過 WINDOW_UPDATE 幀更新,這個字段指定了流 ID 和窗口大小遞增值;
- 流量控制有方向性,即接收方可能根據自己的情況爲每個流乃至整個連接設置任意窗口大小;
- 流量控制可以由接收方禁用,包括針對個別的流和針對整個連接。
- HTTP 2.0 爲數據流和連接的流量控制提供了一個簡單的機制:
服務器推送
HTTP 2.0 新增的一個強大的新功能,就是服務器可以對一個客戶端請求發送多個響應。服務器向客戶端推送資源無需客戶端明確地請求。
HTTP 2.0 連接後,客戶端與服務器交換SETTINGS 幀,藉此可以限定雙向併發的流的最大數量。因此,客戶端可以限定推送流的數量,或者通過把這個值設置爲0 而完全禁用服務器推送。
所有推送的資源都遵守同源策略。換句話說,服務器不能隨便將第三方資源推送給客戶端,而必須是經過雙方確認才行。
PUSH_PROMISE:所有服務器推送流都由PUSH_PROMISE 發端,服務器向客戶端發出的有意推送所述資源的信號。客戶端接收到PUSH_PROMISE 幀之後,可以視自身需求選擇拒絕這個流
幾點限制:
- 服務器必須遵循請求- 響應的循環,只能藉着對請求的響應推送資源
- PUSH_PROMISE 幀必須在返回響應之前發送,以免客戶端出現競態條件。
首部壓縮(HPACK壓縮算法,一邊用index mapping table壓縮,一邊編碼,這個table由靜態表和動態表組成)
http2.0會壓縮首部元數據:在客戶端和服務器端使用“首部表”來跟蹤和存儲之前發送的鍵值對,對於相同的數據,不再通過每次請求和響應發送;“首部表”在http2.0的連接存續期內始終存在,由客戶端和服務器共同漸進地更新;每個新的首部鍵值對要麼追加到當前表的末尾,要麼替換表中之前的值。
http2.0首部差異化傳輸
- 請求與響應首部的定義在HTTP2.0中基本沒有改變,只是所有首部鍵必須全部小寫,而且請求行要獨立爲 :method、:scheme、:host、:path這些鍵值對。
有效的HTTP2.0升級與發現
大多數現代瀏覽器都內置有高效的後臺升級機制,支持HTTP2.0的客戶端在發起新請求之前,必須能發現服務器及所有中間設備是否支持HTTP2.0協議。有三種可能的情況:
- 通過TLS和ALPN發起新的HTTPS連接;
- 根據之前的信息發起新的HTTP連接;
- 沒有之前的信息而發起新的HTTP連接。
HTTPS 協商過程中有一個環節會使用ALPN(應用層協議協商)。減少網絡延遲是HTTP 2.0 的關鍵條件,因此在建立HTTPS 連接時一定會用到ALPN協商。
通過常規非加密信道建立HTTP2.0連接需要多做一點工作。因爲HTTP1.0和HTTP2.0都使用同一個端口(80),有沒有服務器是否支持HTTP2.0的其他任何信息,此時客戶端只能使用HTTP Upgrade機制通過協調確定適當的協議:
Upgrade: HTTP/2.0 ➊ HTTP2-Settings: (SETTINGS payload) ➋ HTTP/1.1 200 OK ➌ HTTP/1.1 101 Switching Protocols ➍ ...
- 1
- 2
- 3
- 4
- 5
➊ 發起帶有HTTP 2.0 Upgrade 首部的HTTP 1.1 請求 ➋ HTTP/2.0 SETTINGS 淨荷的Base64 URL 編碼 ➌ 服務器拒絕升級,通過HTTP 1.1 返回響應 ➍ 服務器接受HTTP 2.0 升級,切換到新分幀
- 1
- 2
- 3
- 4
HTTP2.0二進制分幀簡介
建立HTTP2.0連接後,客戶端與服務器會通過交換幀來通信,幀是基於這個新協議通信的最小單位。所有幀都共享一個8字節的首部,其中包含幀的長度、類型、標誌,還有一個保留位和一個31位的流標識符。
發起新流
- 在發送應用數據之前,必須創建一個新流並隨之發送相應的元數據,比如流優先級、HTTP 首部等;
- 客戶端通過發送HEADERS幀來發起新流;
- 服務器通過發送 PUSH_PROMISE 幀來發起推送流。
發送應用數據
- 創建新流併發送HTTP 首部之後,接下來就是利用DATA 幀。應用數據可以分爲多個DATA 幀,最後一幀要翻轉幀首部的END_STREAM 字段
- HTTP 2.0 標準要求DATA 幀不能超過2的14次方-1(16383)字節。長度超過這個閥值的數據,就得分幀發送。
HTTP2.0幀數據流分析
- HTTP2.0在共享的連接上同時發送請求和響應
- 3 個流的 ID 都是奇數,說明都是客戶端發起的
- 服務器發送的 stream 1 包含多個 DATA 幀,這是對客戶端之前請求的響應數據
- 服務器在交錯發送 stream 1 的 DATA 幀和 stream 3 的 HEADERS 幀,這就是響應的多路複用!
- 客戶端正在發送 stream 5 的 DATA 幀,表明 HEADERS 幀之前已經發送過了。
針對HTTP2.0的優化建議
去掉對1.x的優化
- 每個來源使用一個連接,HTTP 2.0 通過將一個TCP 連接的吞吐量最大化來提升性能。
- 去掉不必要的文件合併和圖片拼接:HTTP 2.0,很多小資源都可以並行發送
- 利用服務器推送:之前針對HTTP 1.x 而嵌入的大多數資源,都可以而且應該通過服務器推送來交付。
雙協議應用策略
- 相同的應用代碼,雙協議部署
- 分離應用代碼,雙協議部署
- 動態HTTP 1.x和HTTP 2.0優化:某些自動化的Web 優化框架在響應請求時動態重寫交付的應用代碼(包括連接、拼合、分區,等等)
- 單協議部署
1.x與2.0的相互轉換
評估服務器質量與性能
- HTTP 2.0 服務器必須理解流優先級;
- HTTP 2.0 服務器必須根據優先級處理響應和交付資源;
- HTTP 2.0 服務器必須支持服務器推送;
- HTTP 2.0 服務器應該提供不同推送策略的實現。
2.0與TLS
兩種可能出現ALPN 協商和TLS 終止的情況
- TLS 連接可能會在 HTTP 2.0 服務器上終止;
- TLS 連接可能會在上游(如負載均衡器)上終止。
第一種情況要求HTTP 2.0 服務器能夠處理TLS;
- 第二種情況建立一條加密信道,直接將非加密的HTTP 2.0 流發送到服務器
負載均衡器、代理及應用服務器
- 要在TLS 之上實現HTTP 2.0通信,終端服務器必須支持 ALPN;
- 儘可能在接近用戶的地方終止 TLS;
- 如果無法支持 ALPN,那麼選擇 TCP 負載均衡模式;
- 如果無法支持 ALPN 且 TCP 負載均衡也做不到,那麼就退而求其次,在非加密信道上使用HTTP 的Upgrade 流;