Http2
- http2 引入了不兼容的new binary framing layer, 所以大版本號增加了
- 除非使用tcp socket,否則看不出http的版本區別 (指Http向上層暴露的API接口,不是說數據一致)
- 基於SPDY
SPDY
google在2009年弄的項目,最大的目標是減少 減低網頁加載延遲,通過解決http1.1 性能瓶頸
- Target a 50% reduction in page load time (PLT).
- Avoid the need for any changes to content by website authors.
- Minimize deployment complexity, and avoid changes in network infrastructure.
- Develop this new protocol in partnership with the open-source community.
- Gather real performance data to (in)validate the experimental protocol.
通過新的 binary framing layer來實現 請求和相應的 多路複用(multiplexing)、優先級排序(prioritization)、首部壓縮
最終提高了55%的速度。
2015年早起,http 2協議被IESG(Steering 指導、操控)通過。
版本比較
http 1.*
- client需要多個connection,來實現 併發(concurrency)、減低延遲(reduce latency)
- 不對request、response的首部壓縮,浪費流量
- 不支持對資源的優先級排序,導致對tcp連接的利用新能底下
http 2
- Binary framing layer
- 首部壓縮
- 更高效使用資源
- 降低延遲
- 允許在 同一 connection上多concurrent(併發)交換信息
- 特別是: 它允許在同一連接上交錯請求和響應消息,並對HTTP頭字段使用高效的編碼。
- 允許對請求進行 優先級排序
- 使重要的請求,優先完成
- push
比較
- 使用更少的tcp connection,降低了 資源的競爭、提高了connection的存活時間
- http2通過binary message framing 更高效處理信息
總結
http2是對http的拓展,而不是替代。status code、header等都保持不變,下面討論關於 底層API的修改。
Binary framing layer (二進制 幀 層)
- http2的核心更改
- 規定http信息的封裝 和 傳輸
- layer:在暴露給應用的 高級http接口 和 底層socket接口之間的 優化的編碼機制
- 不同於 http 1.*在普通文本中通過 換行符分割
- http 2通信都被分割爲 小的message和frame,並採用 二進制的編碼格式
影響
- http 2.0的client、server端必須使用新的 binary
- http1.0的client不會理解只支持http2.0的server,反之亦然
- 可幸的是,應用層 對此無感知
術語 (terminology)
- Streams
- 在connection上建立的 雙向byte通信流
- 用於傳輸message
- Messages
- 完整的 一串 frame
- 可以映射邏輯上 request或response信息
- frames
- http2.0中最小的通信單元
- 都包含 frame header
聯繫
- 所有的通信通過 一個tcp鏈接完成。
- 一個tcp鏈接可carry(進行、搬運) 多個雙向的 Stream
- 每個Stream都有 獨有的識別信息 和 可選的優先級信息
- Stream用於carry 雙向的message
- 每個Message,都代表邏輯上的 Http message(request or response)
- 每個Message,都包含一個或多個frame
- frame是最小的通信單元,用於carry指定的數據類型(例如:header、 部分message等等)
- 不同stream的frame,可以在connection中交錯傳輸,最後通過frame的header裏嵌入的 stream 識別信息 來重新組裝。
小結
- http2.0 將 Http協議的通信 分解爲 binary-encoded frames的交換。
- 將其映射爲 屬於指定stream的 message
- 在一個TCP連接上 通過 多路複用 通信
Request and response multiplexing
Http1.*
- 如果想 多路 並行(parallel)請求 提高效率
- 必須需要 多個TCP connection
- 這是Http1.*的交付模型直接導致的
- 在任意時間,只允許一個response在一個connection內傳遞
- 導致 head-of-line blocking,和底層TCP connection的浪費
Http 2
- 在new binary framing layer中打破,一個connection同時只能有一個response的限制
- 允許一個connction,完全的 多路request、response
- 將一個http信息分解成獨立的 frames
- frames可交叉傳遞
- 最終frame再組裝
HTTP/2最重要的能力
- 將HTTP message分割爲獨立的frames(幀)
- 可交錯傳遞(interleave them)
- 並在接收端 重新組裝frames
由此也引入了其他的好處
- 交叉多個 request, 並行(parallel)處理,而不會被 其中任意一個阻塞
- 交叉多個 response, 並行(parallel)處理,而不會被 其中任意一個阻塞
- 使用 一個 connection,並行 傳遞多個request、response
- 移走不再需要HTTP/1.x的變通方法(concatenated files, image sprites, and domain sharding)
- 提高網絡的可用容量,通過消除不必要的延遲,降低 page 加載時間
好處
- resolves the head-of-line blocking problem found in HTTP/1.x
- eliminates the need for multiple connections to enable parallel processing and delivery of requests and responses
As a result, this makes our applications faster, simpler, and cheaper to deploy.
Stream prioritization
因爲multiplex,使得frame的順序很重要,通過 weight 和 dependence控制:
- 給stream分配weight,區間[1, 256]
- stream可以顯式的dependence (依賴) 其他stream
- 依賴可以構成一個樹形結構
- 頂部的依賴優先執行
- 頂部爲虛擬的一個 root stream
- stream通過 另一個stream唯一識別碼 可以指定依賴,將其作爲parent,parent將優先執行
- 沒指定依賴,則被認爲依賴於 root stream(即優先級最高)
- 當dependence相同時,即多個stream 爲兄弟 stream,則通過 weight佔比,來按比例分配資源
- dependence、weight可以動態調整
One connection per origin
因爲 new binary framing 機制,Http 2不再需要多個TCP連接,來達到併發(parallel)處理。
每個stream可以interleave(交替傳輸)和prioritized(設置優先級)。
因此所有的 HTTP/2 連接都是持久的,沒給origin(起源)只需要一個connection。
- 降低操作的性能消耗
- 降低延遲
- 還提高了server的吞吐量,增大了網絡的容量(capacity)
特別是HTTPS,耗性能的 TLS handshacks
Flow control
Server push
打破了 嚴格的request-response語音,enables one-to-many and server-initiated push workflows(允許1對多 和 服務端推送的工作流)
- PUSH_PROMISE frames
Header compression
HTTP/1.x
這些元數據都是plain text(純文本),一次請求要佔 500–800 bytes ,如果 HTTP cook被使用還會到 kb,
HTTP/2
使用HPACK壓縮格式,壓縮 request、response請求頭的元數據
HPACK壓縮格式:
- It allows the transmitted header fields to be encoded via a static Huffman code, which reduces their individual transfer size.(使用霍夫曼編碼,降低單次transfer消耗)
- It requires that both the client and server maintain and update an indexed list of previously seen header fields (in other words, it establishes a shared compression context), which is then used as a reference to efficiently encode previously transmitted values.(採用index,複用相同header)