HTTP/1.1 與 HTTP/2.0
HTTP/1.1 持久連接
非持久連接
持久連接
小結
- 非持久HTTP連接的固定時間成本
- 至少兩次網絡往返: 握手、請求和響應
- 服務處理速度越快,固定延遲的影響就越大
- 持久連接避免TCP連接時的三次握手,消除TCP的慢啟動
HTTP/1.1管道
從上面持久連接的圖我們能看到Server處理完HTML后需要response給Client,進而Client發起css的request到Server,這段時間Server是空閑的。
所以使用管道盡早發送請求,不被每次響應阻塞。
管道並行處理HTTP請求
小結
- HTTP/1.1 局限性
- 只能嚴格串行地返回響應,不允許一個連接上的多個響應交錯到達
- 管道的問題
- 並行處理請求時,服務器必須緩沖管道中的響應,占用服務器資源
- 由於失敗可能導致重復處理,非冪等的方法不能pipeline化
- 由於中間代理的兼容性,可能會破壞管道
- 管道的應用非常有限
HTTP/1.1 協議開銷
- 每個HTTP請求都會攜帶500~800字節的header
- 如果使用了cookie,每個HTTP請求會增加幾千字節的協議開銷
- HTTP header以純文本形式發送,不會進行任何壓縮
- 某些時候HTTP header開銷會超過實際傳輸的數據一個數量級
- 例如訪問RESTful API時返回JSON格式的響應
HTTP/1.1性能優化建議
- 由於HTTP/1.1不支持多路復用
- 瀏覽器支持每個主機打開多個連接(例如Chrome是6個)
- 應用使用多域名,將資源分散到多個子域名
- 瀏覽器連接限制針對的是主機名,不是IP地址
- 缺點
- 消耗客戶端和服務器資源
- 域名分區增加了額外的DNS查詢
- 避免不了TCP的慢啟動
- 減少請求次數
- 把多個JavaScript或CSS組合為一個文件
- 把多張圖片組合為一個更大的復合的圖片
- inlining內聯,將圖片嵌入到CSS或者HTML文件中,減少網絡請求次數
以上優化增加應用的復雜度,導致緩存、更新等問題,只是權宜之計
HTTP/2 目標
- 性能優化
- 支持請求與響應的多路復用
- 支持請求優先級和流量控制
- 支持服務器端推送
- 壓縮HTTP header降低協議開銷
- HTTP的語義不變
- HTTP方法、header、狀態碼、URI
HTTP/2 二進制分幀層
- 引入新的二進制分幀數據層
- 將傳輸的信息分割為消息和幀,並采用二進制格式的編碼
HTTP/2 核心概念
- 流(Stream)
- 已建立的連接上的雙向字節流
- 該字節流可以攜帶一個或多個消息
- 消息(Message)
- 與請求/響應消息對應的一系列完整的數據幀
- 幀(Frame)
- 通信的最小單位
- 每個幀包含幀首部,標識出當前幀所屬的流
- 所有HTTP/2通信都在一個TCP連接上完成
- 流是連接中的一個虛擬信道,可以承載雙向的消息
- 一個連接可以承載任意數量的流,每個流都有一個唯一的整數標識符(1、2...N)
- 消息是指邏輯上的HTTP消息,比如請求、響應等
- 消息由一或多個幀組成,這些幀可以交錯發送,然后根據每個幀首部的流標識符重新組裝
HTTP/2請求與響應的多路復用
- HTTP/1.x中,如果客戶端想發送多個並行的請求,那么必須使用多個TCP連接
- HTTP/2中,客戶端可以使用多個流發送請求,同時HTTP消息被分解為互不依賴的幀,交錯傳輸,最后在另一端重新組裝
HTTP/2 請求優先級
- HTTP/2允許每個流關聯一個31bit的優先值
- 0 最高優先級
- 2^31 -1 最低優先級
- 瀏覽器會基於資源的類型、在頁面中的位置等因素,決定請求的優先次序
- 服務器可以根據流的優先級,控制資源分配,優先將高優先級的幀發送給客戶端
- HTTP/2沒有規定具體的優先級算法
HTTP/2 流量控制
- 流量控制有方向性,即接收方可能根據自己的情況為每個流,乃至整個連接設置任意窗口大小
- 連接建立后,客戶端與服務器交換SETTINGS幀,設置 雙向的流量控制窗口大小
- 流量控制窗口大小通過WINDOW_UPDATE幀更新
- HTTP/2流量控制和TCP流量控制的機制相同,但TCP流量控制不能對同一個連接內的多個流實施差異化策略
HTTP/2 服務器端推送
- 服務器可以對一個客戶端請求發送多個響應
- 服務器通過發送PUSH_PROMISE幀來發起推送流
- 客戶端可以使用HTTP header向服務器發送信號,列出它希望推送的資源
- 服務器可以智能分析客戶端的需求,自動推送關鍵資源
HTTP header壓縮
- HTTP/2使用HPACK壓縮格式壓縮請求/響應頭
- 通過靜態霍夫曼碼對發送的header字段進行編碼,減小了它們的傳輸大小
- 客戶端和服務器使用索引表來維護和更新header字段。對於相同的數據,不再重復發送
參考鏈接:
https://hpbn.co/http1x/
https://hpbn.co/http2/
https://github.com/mz1999/blog/blob/master/docs/http2.md