二進制協議:HTTP/2 是一個二進制協議。在 HTTP/1.1 版中,報文的頭信息必須是文本(ASCII 編碼),數據體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協議,頭信息和數據體都是二進制,并且統稱為"幀",可以分為頭信息幀和數據幀。 幀的概念是它實現多路復用的基礎。
多路復用: HTTP/2 實現了多路復用,HTTP/2 仍然復用 TCP 連接,但是在一個連接里,客戶端和服務器都可以同時發送多個請求或回應,而且不用按照順序一一發送,這樣就避免了"隊頭堵塞"【1】的問題。
數據流: HTTP/2 使用了數據流的概念,因為 HTTP/2 的數據包是不按順序發送的,同一個連接里面連續的數據包,可能屬于不同的請求。因此,必須要對數據包做標記,指出它屬于哪個請求。HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流。每個數據流都有一個獨一無二的編號。數據包發送時,都必須標記數據流 ID ,用來區分它屬于哪個數據流。
頭信息壓縮: HTTP/2 實現了頭信息壓縮,由于 HTTP 1.1 協議不帶狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重復的,比如 Cookie 和 User Agent ,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。HTTP/2 對這一點做了優化,引入了頭信息壓縮機制。一方面,頭信息使用 gzip 或 compress 壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發送同樣字段了,只發送索引號,這樣就能提高速度了。
服務器推送: HTTP/2 允許服務器未經請求,主動向客戶端發送資源,這叫做服務器推送。使用服務器推送提前給客戶端推送必要的資源,這樣就可以相對減少一些延遲時間。這里需要注意的是 http2 下服務器主動推送的是靜態資源,和 WebSocket 以及使用 SSE 等方式向客戶端發送即時數據的推送是不同的。
【1】隊頭堵塞:隊頭阻塞是由 HTTP 基本的“請求 - 應答”模型所導致的。HTTP 規定報文必須是“一發一收”,這就形成了一個先進先出的“串行”隊列。隊列里的請求是沒有優先級的,只有入隊的先后順序,排在最前面的請求會被最優先處理。如果隊首的請求因為處理的太慢耽誤了時間,那么隊列里后面的所有請求也不得不跟著一起等待,結果就是其他的請求承擔了不應有的時間成本,造成了隊頭堵塞的現象。