HTTP1.1、HTTP2、HTTP3 演變

ML李嘉圖發表於2022-04-01

推薦閱讀:https://www.cnblogs.com/zwtblog/tag/計算機網路/

計算機網路-相關文章可以移步:https://www.cnblogs.com/zwtblog/tag/計算機網路/

HTTP 基本概念

HyperText Transfer Protocol -- 超文字傳輸協議

狀態碼分類:

完整詳情見:https://www.cnblogs.com/zwtblog/p/16077173.html

分類 分類描述
1** 資訊,伺服器收到請求,需要請求者繼續執行操作
2** 成功,操作被成功接收並處理
3** 重定向,需要進一步的操作以完成請求
4** 客戶端錯誤,請求包含語法錯誤或無法完成請求
5** 伺服器錯誤,伺服器在處理請求的過程中發生了錯誤

各個版本示意圖:

HTTP/1.1 相⽐ HTTP/1.0 提⾼了什麼效能?

HTTP/1.1 相⽐ HTTP/1.0 效能上的改進:

  • 使⽤ TCP ⻓連線(keepalive)的⽅式改善了 HTTP/1.0 短連線造成的效能開銷。
  • ⽀持管道(pipeline)⽹絡傳輸,只要第⼀個請求發出去了,不必等其回來,就可以發第⼆個請求出去,可以
    減少整體的響應時間。

但 HTTP/1.1 還是有效能瓶頸:

  • 請求 / 響應頭部(Header)未經壓縮就傳送,⾸部資訊越多延遲越⼤。只能壓縮 Body 的部分;
    傳送冗⻓的⾸部。每次互相傳送相同的⾸部造成的浪費較多;
  • 伺服器是按請求的順序響應的,如果伺服器響應慢,會招致客戶端⼀直請求不到資料,也就是隊頭阻塞
  • 沒有請求優先順序控制;
  • 請求只能從客戶端開始,伺服器只能被動響應

HTTP/1.1如何優化?

  • 避免發請求 -- 快取
  • 減少請求次數
    • 減少重定向
    • 合併請求
    • 延遲傳送
  • 減少響應資料
    • 有損/無失真壓縮

避免發請求

快取

伺服器在傳送 HTTP 響應時,有過期的時間,並把這個資訊放到響應頭部中,這樣客戶端在檢視響應頭部的資訊時,⼀旦發現快取的響應是過期的,則就會重新傳送⽹絡請求。

如果資料並未變更,也可以對比摘要。

減少請求次數

減少重定向

合理使用代理伺服器

合併請求

例如合併圖片

延遲傳送請求

例如 在部落格園訪問我的部落格的時候,頁面時一次性載入出來的,是否可以優化成⽤戶向下滑動⻚⾯的時候,再向伺服器獲取接下來的資源,這樣就達到了延遲傳送請求的效果。

HTTP/1.1 的效能瓶頸,HTTP/2 做了什麼優化?

最⼤效能問題就是 HTTP/1.1 的⾼延遲,主要原因如下⼏個:

  • 併發連線有限,瀏覽器最⼤併發有限, 握⼿耗時,以及TCP 慢啟動過程給流量帶來的影響。
  • 隊頭阻塞,同⼀連線只能在完成⼀個 HTTP 事務(請求和響應)後,才能處理下⼀個事務。
  • HTTP 頭部巨⼤且重複,由於 HTTP 協議是⽆狀態的,每⼀個請求都得攜帶 HTTP 頭部。
  • 不⽀持伺服器推送訊息,因此當客戶端需要獲取通知時,只能通過定時器不斷地拉取訊息。

HTTP/2 只在應⽤層做了改變,還是基於 TCP 協議傳輸,應⽤層⽅⾯為了保持功能上的相容,HTTP/2 把 HTTP 分
解成了「語義」和「語法」兩個部分,「語義」層不做改動,與 HTTP/1.1 完全⼀致,⽐如請求⽅法、狀態碼、頭
欄位等規則保留不變。

但是,HTTP/2 在「語法」層⾯做了很多改造,基本改變了 HTTP 報⽂的傳輸格式。

HTTP/2的優化

  • 頭部壓縮
  • 二進位制幀
  • 併發傳輸
  • 主動推送資源

頭部壓縮

HTTP/1.1 報⽂中 Header 部分存在的問題:含很多固定的欄位,⽐如Cookie、User Agent、Accept 等,⼤量的請求和響應的報⽂⾥有很多欄位值都是重複的。欄位是 ASCII 編碼的。

HTTP/2 對 Header 部分做了⼤改造,把以上的問題都解決了。

HTTP/2 沒使⽤常⻅的 gzip 壓縮⽅式來壓縮頭部,⽽是開發了 HPACK 演算法,HPACK 演算法主要包含:

  • 靜態字典;(高頻頭部或者欄位,共61種)
  • 動態字典;(自行構建。Index 62 起步)
  • Huffman 編碼 編碼(壓縮演算法);

客戶端和伺服器兩端都會建⽴和維護「字典」,⽤⻓度較⼩的索引號表示重複的字串,再⽤ Huffman 編碼壓縮資料,可達到 50%~90% 的⾼壓縮率。

Web 伺服器都會提供類似 http2_max_requests 的配置,⽤於限制⼀個連線上能夠傳輸的請求數量,

避免動態表⽆限增⼤,請求數量到達上限後,就會關閉 HTTP/2 連線來釋放記憶體。

二進位制幀

HTTP/2 將 HTTP/1 的⽂本格式改成⼆進位制格式傳輸資料,使⽤位運算能⾼效解析。

HTTP/2 把響應報⽂劃分成了兩個幀(Frame), HEADERS(⾸部)和 DATA(訊息負載) 是幀的型別。

併發傳輸

通過 Stream 這個設計,多個 Stream 復⽤⼀條 TCP 連線,達到併發的效果,解決了HTTP/1.1 隊頭阻塞的問題,提⾼了 HTTP 傳輸的吞吐量。

HTTP 訊息可以由多個 Frame 構成,以及 1 個 Frame 可以由多個 TCP 報⽂構成。

在 HTTP/2 連線上,不同 Stream 的幀是可以亂序傳送的(因此可以併發不同的 Stream ),因為每個幀的頭部會攜帶 Stream ID 資訊,所以接收端可以通過 Stream ID 有序組裝成 HTTP 訊息,⽽同一 Stream 內部的幀必須是嚴格有序的。

HTTP/2 還可以對每個 Stream 設定不同優先順序,幀頭中的「標誌位」可以設定優先順序

主動推送資源

客戶端發起的請求,必須使⽤的是奇數號 Stream,伺服器主動的推送,使⽤的是偶數號 Stream。
伺服器在推送資源時,會通過 PUSH_PROMISE 幀傳輸 HTTP 頭部,並通過幀中的 Promised Stream ID 欄位告知客戶端,接下來會在哪個偶數號 Stream 中傳送包體。

HTTP/3

HTTP/2 協議是基於 TCP 實現的,於是存在的缺陷有三個。

  • 隊頭阻塞;(TCP保證完整 有序導致的)
  • TCP 與 TLS 的握⼿時延遲;
  • ⽹絡遷移需要重新連線;

由下圖可知:此次升級使用 谷歌制定的一種基於UDP的低時延的網際網路傳輸層協議, QUIC(Quick UDP Internet Connection) 。再就是幀格式在HTTP/2的基礎上做了一些改變。

為什麼HTTP/3要基於UDP?可靠嗎?

詳情見:https://www.cnblogs.com/zwtblog/p/16081957.html

肝不動了,見諒。下次更新,更新了加連結。

參考

相關文章