HTTP/2(2015年發佈)已經發布快10年了,雲原生社區的RPC框架中,gRPC 是直接基於 HTTP/2 實現。Dubbo 框架的默認協議,也從原先基於 TCP協議 的 dubbo協議,換成基於 HTTP/1.1、HTTP/2的 triple協議。
可能網站、框架還在使用 HTTP/1.1(1997年發佈),但隨着對系統性能的要求越來越高,HTTP/2 實在應該好好了解一番。
從 HTTP/1.0 到 HTTP/2,每個版本的升級,都存在解決各自最核心的問題,下面從各自問題入手,逐漸瞭解各版本的功能提升。
1. HTTP/1.0 - 獨立連接問題
HTTP/1.1 通過引入持久連接(Keep-Alive)機制,顯著改進了 TCP 連接的複用問題。與 HTTP/1.0 的短連接方式相比,HTTP/1.1 的持久連接減少了連接建立和關閉的開銷,優化了資源利用,提高了網絡性能,從而顯著提升了用户體驗和 Web 應用的效率。
1.1. HTTP/1.0 的 TCP 連接管理
1. 短連接
-
默認行為:
- HTTP/1.0 默認使用短連接。每次請求和響應完成後,TCP 連接都會被關閉。這意味着每個資源(如 HTML 文檔、圖片、CSS 文件等)都需要建立一個新的 TCP 連接。
-
問題:
- 頻繁的連接建立和關閉:每次請求都需要進行 TCP 三次握手和四次揮手,增加了網絡延遲。
- 資源消耗:頻繁的連接操作消耗了大量的服務器資源,如 CPU 和內存。
- 帶寬浪費:每次建立連接都需要傳輸 TCP 握手數據,浪費了帶寬。
2. Keep-Alive 擴展
-
非標準支持:
- 儘管 HTTP/1.0 不正式支持持久連接,但一些實現引入了
Connection: Keep-Alive頭部,允許在一個連接上發送多個請求。這是一種非標準的擴展,不同實現之間可能存在兼容性問題。
- 儘管 HTTP/1.0 不正式支持持久連接,但一些實現引入了
1.2. HTTP/1.1 的 TCP 連接管理
1. 持久連接(Persistent Connections)
-
默認行為:
- HTTP/1.1 默認啓用持久連接。除非明確指定
Connection: close,否則連接會保持打開狀態,允許在同一連接上發送多個請求和響應。
- HTTP/1.1 默認啓用持久連接。除非明確指定
-
優勢:
- 減少連接建立和關閉的開銷:減少了 TCP 三次握手和四次揮手的次數,降低了網絡延遲。
- 優化資源利用:減少了服務器的 CPU 和內存消耗,提高了資源利用率。
- 節省帶寬:避免了頻繁的 TCP 握手數據傳輸,節省了帶寬。
2. Keep-Alive 參數
-
連接保持時間:
- HTTP/1.1 允許客户端和服務器通過
Keep-Alive頭部指定連接保持的時間。例如,服務器可以設置Keep-Alive: timeout=5, max=100,表示連接最多保持 5 秒,最多處理 100 個請求。
- HTTP/1.1 允許客户端和服務器通過
-
連接管理:
- 客户端和服務器可以靈活地管理連接的生命週期,根據需要調整連接的保持時間和最大請求數。
1.3. 實際應用和影響
1. 性能提升
-
減少延遲:
- 持久連接顯著減少了每個請求的延遲,特別是對於需要加載多個資源的網頁。例如,一個包含多個圖片和腳本的網頁可以通過一個連接完成所有資源的加載,大大減少了總的加載時間。
-
提高吞吐量:
- 通過減少連接建立和關閉的開銷,持久連接提高了網絡的吞吐量,使得服務器能夠處理更多的請求。
2. 資源優化
-
服務器資源:
- 持久連接減少了服務器的 CPU 和內存消耗,使得服務器能夠更高效地處理請求,支持更高效的併發連接。
-
網絡資源:
- 持久連接減少了網絡帶寬的浪費,提高了帶寬利用率,特別是在高延遲和低帶寬的網絡環境中效果顯著。
3. 用户體驗
-
更快的頁面加載:
- 持久連接顯著提升了頁面加載速度,改善了用户體驗,特別是在加載複雜的網頁時。
-
更好的響應時間:
- 減少的延遲和更高的吞吐量使得 Web 應用能夠更快地響應用户請求,提供了更流暢的交互體驗。
2. HTTP/1.1 - 隊頭阻塞問題
HTTP/1.1 的隊頭阻塞問題主要源於其串行化的請求/響應模型。在一個連接上必須等待前一個請求的響應完成後才能發送下一個請求,這種設計限制了連接的效率,特別是在需要處理多個請求時。通過升級到 HTTP/2 或優化網絡和服務器性能,可以有效緩解或解決這一問題。
2.1. 串行請求/響應模型
-
單一請求處理:
- HTTP/1.1 在一個 TCP 連接上只能同時處理一個請求和一個響應。這意味着必須等待當前請求的響應完成後,才能發送下一個請求。
- 這種設計導致了一個關鍵問題:如果一個請求的響應需要較長時間(可能是網絡傳輸慢,可能是服務器業務處理慢),後續的請求就會被阻塞,無法在同一個連接上並行處理。
-
典型場景:
- 在加載網頁時,瀏覽器需要從同一個服務器請求多個資源(如 HTML、CSS、JavaScript、圖像等)。如果一個資源請求的響應較慢,其他資源的請求就會被阻塞,導致整個頁面加載變慢。
2.2. 瀏覽器的連接限制
如果基於單個 TCP 連接的 HTTP 請求,存在阻塞問題,那麼打開多個 TCP 連接,是解決 HTTP/1.1 阻塞問題最簡單方法。不過大多數瀏覽器最多隻可以為每個域名打開6個連接,即6個 TCP 連接,即可以有6個 HTTP 請求同時並行開啓。
突破請求數限制做的努力
為了進一步突破6個連接的現在,許多網站從子域名(例如:static.example.com)提供css、js等靜態資源,Web瀏覽器從而可以為每個新域名打開另外的6個連接。這種技術叫 域名分片。
但瀏覽器既然限制併發的連接上限,肯定有自己的意義。多個 TCP 連接增加了服務器和網絡的負擔,因為每個連接都需要進行 TCP 握手和維護狀態,不僅增加了網絡擁塞,維護連接需要消耗更多的內存和CPU等資源。
2.3. 資源請求的依賴性
-
資源加載順序:
- 在複雜的網頁中,某些資源可能依賴於其他資源的加載完成。例如,JavaScript 文件可能需要在特定的 CSS 文件加載後執行。
- 如果某個關鍵資源的請求被阻塞,可能會導致整個頁面的渲染延遲,從而影響用户體驗。
2.4. 網絡和服務器因素
-
服務器處理時間:
- 如果服務器處理某個請求需要較長時間,響應會被延遲,從而導致後續請求被阻塞。
-
網絡延遲:
- 網絡條件不佳(如高延遲或丟包)也會加劇隊頭阻塞問題,因為它會增加請求和響應的時間。
2.5. 請求資源大
1. 文本格式體積大
HTTP/1.1 是一個簡單的文本協議,這種簡單性也帶來的一些問題,儘管消息體可以包含二進制數據(比如圖片等),但請求和首部都需要是文本的形式。
文本格式對於人類來説很友好,但對於機器並不友好。向HTTP首部中添加換行符,可以進行一些HTTP攻擊。最主要的是消息體會比較大,不如二進制體積小。
2. 請求頭冗餘
HTTP/1.1 請求頭的應用場景很多了,請求頭所佔的數據量越來越大,但內容大多重複。
就算只有主頁需要 cookie,每個發向服務器的 HTTP 請求中都會包含 cookie。通常靜態資源,如:圖片、css、js 都不需要 cookie的。包括像 Content-Security-Policy 這種關於安全的頭部,會導致頭部非常大,從而使效率低下的問題越來越突出。通常一個 GET 請求中請求參數不大,但頭部數據可能卻佔了幾K。
頭部冗餘導致帶寬浪費,尤其在高延遲和低帶寬網絡中,對性能影響顯著。完全可以利用其較高的重複性好好優化。
3. 合併請求做的努力
另一個常見的優化思路就是發送更少的請求,包括:減少不必要的請求(比如在瀏覽器中緩存靜態資源)。
對於圖片來説,有種叫做“精靈圖”的打包技術。如果網站上有很多圖標,如果每個圖標都是一張獨立的圖片,會導致很多低效的HTTP請求排隊。以為圖片比較小,所以相對於下載這些圖片所需要的時間,發送請求的時間可能會較長。
所以,可以將它們合併到一張大的圖片裏,然後使用CSS來定位圖片位置,讓它們看起來像是獨立的圖片,這樣更高效。
如果是 CSS、JS文件,前端框架通常也會將多個文件合併成一個文件,這樣需要的請求數就少了,總的代碼量並不會變。在合併文件的時候,通常還會去掉代碼中不必要的空格、註釋等。
這種思路不錯,但也會帶來一定的複雜性。如果需要修改某個圖標,還需要重新維護整個精靈圖。
3. HTTP/2 - 解決隊頭阻塞
HTTP/2 通過一系列技術革新,去解決 HTTP/1.1 的隊頭阻塞問題。HTTP/1.1 的隊頭阻塞主要是因為其在一個 TCP 連接上只能同時處理一個請求和響應,這種串行化的處理方式導致了性能瓶頸。HTTP/2 的設計目標之一就是消除這種限制。以下是 HTTP/2 如何解決隊頭阻塞問題的詳細介紹:
3.1. 多路複用
-
概念:
- HTTP/2 允許在一個單一的 TCP 連接上同時發送和接收多個請求和響應,而不必按照請求的順序來等待響應。這是通過引入“流”(streams)的概念實現的。
-
工作機制:
- 在 HTTP/2 中,數據被分成更小的幀,這些幀可以在同一個連接中並行傳輸。每個流都有一個唯一的標識符,數據幀可以亂序到達和處理。
- 這種機制避免了 HTTP/1.1 中必須等待前一個請求完成後才能發送下一個請求的限制。
-
優勢:
- 通過多路複用,HTTP/2 消除了單個請求阻塞其他請求的情況,提高了數據傳輸效率和網絡利用率。
3.2. 二進制分幀
-
高效傳輸:
- HTTP/2 使用二進制格式傳輸數據,取代了 HTTP/1.1 的文本格式。這種格式更緊湊,解析更快,減少了由於格式解析而導致的延遲。
-
幀的獨立性:
- 數據被分割成二進制幀,幀是獨立的,這樣即使某個流中的幀被延遲或丟失,也不會影響其他流的數據傳輸。
3.3. 流優先級和依賴
-
優先級設置:
- HTTP/2 允許客户端為每個流設置優先級,服務器可以根據這些優先級來決定資源分配策略。
-
依賴關係:
- 流可以相互依賴,形成一個依賴樹結構,服務器可以根據優先級和依賴關係優化資源處理。
-
效果:
- 通過優先級和依賴關係,關鍵請求可以被優先處理,進一步減少可能的阻塞和延遲。
3.4. 頭部壓縮
HTTP/2 的頭部壓縮機制使用了 HPACK 算法來減少 HTTP 頭部信息的冗餘傳輸,從而提高傳輸效率。這一機制通過靜態表和動態表來壓縮頭部字段及其值,並使用哈夫曼編碼進行進一步壓縮。以下是對 HPACK 頭部壓縮的詳細介紹,並附帶一個簡單示例。
3.4.1. HPACK 壓縮機制
1. 靜態表
- 靜態表是一個預定義的頭部字段及其常用值的集合。在 HPACK 中,這個表是固定的,包含了常用的 HTTP 頭部字段,如
:method,:path,:authority等。 - 使用靜態表時,可以通過索引直接引用這些常用的頭部字段,減少傳輸數據量。
2. 動態表
- 動態表是在連接期間動態維護的表,用於存儲最近使用的頭部字段和值。每當一個新的頭部字段被傳輸時,它可以被添加到動態表中。
- 動態表是可變大小的,服務器和客户端可以根據需要調整其大小。
3. 哈夫曼編碼
- 哈夫曼編碼是一種可變長度的編碼方法,用於對頭部字段的名稱和值進行進一步壓縮。它通過對頻繁出現的字符使用更短的編碼來減少數據量。
3.4.2. 示例
假設我們有一個 HTTP 請求,其頭部如下:
:method: GET
:scheme: https
:authority: www.example.com
:path: /index.html
user-agent: Mozilla/5.0
1. HPACK 壓縮過程
-
使用靜態表:
:method: GET和:scheme: https可以在靜態表中找到對應的索引,因此可以直接使用索引來引用。
-
使用動態表:
:authority: www.example.com和user-agent: Mozilla/5.0可能是首次傳輸,因此會被添加到動態表中以供後續請求使用。
-
哈夫曼編碼:
:path: /index.html和其他未在靜態表中的值可以使用哈夫曼編碼進行壓縮。
靜態表 VS 動態表
- 靜態表:內容固定,不會隨連接變化。它包含常用的、標準化的頭部字段及其常見值。
- 動態表:內容可變,隨着連接的進展動態更新,存儲在連接過程中實際傳輸的頭部字段和值。
可以看到靜態表內容是固定的。動態表更靈活,但需要動態管理,增加了實現的複雜性,涉及內存和性能的開銷,所以性能上不如靜態表。
因此,如果內容在靜態表中存在,協議優先使用靜態表,否則再考慮使用動態表。
壓縮後的傳輸
通過上述步驟,頭部信息會被轉換為一系列的二進制數據,這些數據比原始的頭部信息要小得多。在接收端,這些二進制數據會被解碼成原始的頭部信息。
3.5. 服務器推送
HTTP/2 的服務器推送(Server Push)是一項強大的功能,它允許服務器在客户端請求某個資源之前,主動將相關資源推送到客户端。這種機制可以顯著減少網頁加載時間,尤其是在高延遲網絡環境中。以下是關於 HTTP/2 服務器推送的詳細介紹。
1. 工作原理
-
客户端請求:
- 客户端發起一個 HTTP 請求,比如請求一個 HTML 頁面。
-
服務器識別依賴:
- 服務器在處理請求時,可以識別出該頁面所需的其他資源,比如 CSS、JavaScript 或圖片文件。
-
發送推送承諾(Push Promise):
- 服務器向客户端發送一個
PUSH_PROMISE幀。這一幀告知客户端將要推送的資源,幷包含這些資源的請求頭信息。 PUSH_PROMISE幀的發送順序是在客户端請求的響應之前,這樣客户端可以知道即將接收到哪些資源。
- 服務器向客户端發送一個
-
主動推送資源:
- 服務器隨後將這些資源作為響應推送給客户端,類似於正常的 HTTP 響應。
-
客户端處理:
- 客户端接收這些推送的資源後,可以將其緩存,以便後續使用,而無需再發起請求。
2. 優勢
- 減少延遲:通過提前發送資源,減少了客户端請求這些資源的延遲。
- 優化加載順序:服務器可以根據頁面依賴關係優化資源的推送順序,提高頁面加載效率。
- 減少請求次數:避免了客户端在解析 HTML 後再發起的額外請求,減少了請求次數和服務器負載。
3. 示例
假設一個網頁需要加載多個資源:
- 客户端請求
/index.html。 - 服務器識別出
/index.html依賴於/style.css和/script.js。 - 服務器發送
PUSH_PROMISE幀給客户端,表示將推送/style.css和/script.js。 - 服務器隨後主動推送
/style.css和/script.js的內容。 - 客户端接收這些資源並緩存,以便在解析 HTML 時直接使用。
4. HTTP、TCP隊頭阻塞
前面講解 HTTP/1.1 的隊頭阻塞問題,其實我們也常接觸到 TCP 隊頭阻塞問題,這兩者不是同一個概念。
雖然 HTTP/1.1 也是基於 TCP協議創建連接到,HTTP/1.1 隊頭阻塞問題,也會因為 TCP 隊頭阻塞問題受到影響,但二者不能劃等號。
HTTP/1.1 的隊頭阻塞問題主要是由於其串行請求/響應模型導致的,而 TCP 的隊頭阻塞問題則源於其可靠傳輸的順序保證機制。HTTP/1.1 的問題可以通過升級到 HTTP/2 來解決,而 TCP 的問題可以通過使用 QUIC 協議或網絡優化來緩解。通過針對不同層次的問題採取適當的解決方案,可以顯著提高網絡傳輸效率和用户體驗。
4.1. HTTP/1.1 隊頭阻塞
1. 產生原因
-
串行請求/響應模型:
- 在 HTTP/1.1 中,一個 TCP 連接上通常只能同時處理一個請求和一個響應。這意味着在一個連接中,必須等待當前請求的響應完成後,才能開始處理下一個請求。
- 這種串行化的處理方式導致了隊頭阻塞問題:如果一個請求的響應時間較長,後續的請求就會被阻塞,無法及時處理。
-
有限的併發連接:
- 瀏覽器為了減輕單連接的限制,通常會對每個域名開啓多個併發連接(通常是 6 個左右)。然而,連接數的增加會導致服務器負載增加和網絡資源浪費。
- 即便如此,多個連接之間的請求仍然是串行化的,無法完全消除隊頭阻塞的問題。
2. 影響
- 頁面加載速度慢:當一個請求被阻塞時,後續請求的資源無法及時獲取,導致頁面加載變慢。
- 用户體驗下降:由於資源加載緩慢,用户可能會感到網頁響應遲緩,影響用户體驗。
4.2. TCP 隊頭阻塞
1. 產生原因
-
可靠傳輸的順序保證:
- TCP 協議旨在提供可靠的、有序的數據傳輸。它通過序列號來確保數據包按序到達。接收方必須按照序列號的順序來處理數據包。
- 如果某個數據包丟失或延遲到達,接收方必須等待該數據包被重傳或到達,才能繼續處理後續的數據包。
-
網絡抖動和丟包:
- 在實際網絡環境中,數據包可能會因為各種原因(如網絡擁塞、硬件故障等)而丟失、延遲或亂序。
- TCP 的順序保證機制要求在處理後續數據之前,必須解決這些丟失或延遲的問題,這會導致整個連接的阻塞。
2. 影響
- 傳輸延遲增加:因為需要等待丟失的數據包被重傳,整個數據流的傳輸延遲會增加。
- 吞吐量降低:由於某個數據包的丟失或延遲,整個連接的吞吐量會降低,因為後續的數據包無法被及時處理。
4.3. 兩者之間的關係
-
層次不同:
- TCP 隊頭阻塞發生在 傳輸層,而 HTTP 隊頭阻塞發生在 應用層。這意味着它們發生在網絡協議棧的不同層次。
-
間接影響:
- 雖然 TCP 的隊頭阻塞不會直接導致 HTTP 的隊頭阻塞,但它會間接影響 HTTP 請求的效率。
- 在 HTTP/1.1 中,如果 TCP 連接上的某個數據包丟失,整個連接上的所有 HTTP 請求都會受到影響,因為 TCP 必須等待丟失的數據包重傳。
-
HTTP/2 的改進:
- HTTP/2 通過多路複用技術在應用層解決了 HTTP/1.1 的隊頭阻塞問題。即使在同一個 TCP 連接上,多個請求和響應也可以同時進行。
- 然而,HTTP/2 仍然依賴於 TCP,因此仍然可能受到 TCP 隊頭阻塞的影響。如果 TCP 層發生隊頭阻塞,HTTP/2 的所有流都會受到影響。
4.4. 解決方案概述
4.4.1. HTTP/2 不能真正解決問題
按照前文的方式,從 HTTP/1.1 升級到 HTTP/2,可以“解決”隊頭阻塞的問題。HTTP/2 引入了多路複用技術,允許在一個 TCP 連接上同時處理多個請求和響應,避免了串行化處理的瓶頸。
雖然 HTTP/2 在應用層有效地緩解了 HTTP 層面的隊頭阻塞,但由於其依賴於 TCP 作為底層傳輸協議,仍然會受到 TCP 隊頭阻塞問題的影響。只有也解決了傳輸層的隊頭阻塞問題,才能説HTTP應用層真正解決了。
4.4.2.TCP 隊頭阻塞的解決
HTTP/2 無法徹底解決隊頭阻塞問題,解決傳輸層隊頭阻塞問題的答案在 HTTP/3,HTTP/3 使用的傳輸層協議是 QUIC協議。QUIC 運行在 UDP 之上,而不是 TCP。
QUIC(Quick UDP Internet Connections)是由 Google 開發的一種傳輸層網絡協議,旨在提高網絡應用的性能和安全性。QUIC 的設計初衷是解決 TCP 的一些固有缺陷,特別是在高延遲和高丟包率的網絡環境中。它已經被廣泛應用於 HTTP/3 中。
QUIC 協議通過多個創新機制解決了傳統 TCP 中的隊頭阻塞問題,以下是詳細説明:
1. 多路複用的獨立流
-
流的獨立性:
- QUIC 協議允許在單個連接中同時進行多個獨立的流傳輸。每個流都有自己的流 ID,並且在傳輸過程中是彼此獨立的。
- 在 TCP 中,如果一個數據包丟失,接收端必須等待該數據包被重傳後才能處理後續的數據包,這就導致了隊頭阻塞。
- QUIC 通過允許不同流獨立傳輸,使得即便一個流中的數據包丟失,也不會影響其他流的傳輸和處理。
2. 基於 UDP 的實現
-
去除 TCP 順序依賴:
- QUIC 使用 UDP 作為底層協議,而不是 TCP。這意味着 QUIC 不受 TCP 的順序交付限制,可以自由實現自己的流控制和擁塞控制。
- 因為 QUIC 在用户態實現,可以直接管理數據包的傳輸順序和重傳策略,而無需依賴內核態的 TCP 棧。
3. 高效的重傳機制
-
快速重傳:
- QUIC 協議支持快速重傳機制。當檢測到數據包丟失時,QUIC 可以立即重傳丟失的數據包,而不需要等待傳統的 TCP 超時。
- QUIC 的設計允許接收方發送關於丟失數據包的精確反饋,發送方可以根據這些反饋迅速進行重傳。
4. 靈活的擁塞控制
-
自定義擁塞控制算法:
- QUIC 允許實現自定義的擁塞控制算法,這使得它可以在不同網絡條件下優化數據傳輸。
- 由於其在用户態實現,開發者可以根據具體需求調整擁塞控制策略,以減少丟包對傳輸效率的影響。
5. 前向糾錯
-
糾錯機制:
- QUIC 可以在傳輸數據時添加冗餘信息,使得接收方能夠在一定程度上自行糾正丟失的數據包,而無需重傳。這進一步減少了因丟包帶來的延遲。
6. 0-RTT 連接建立
-
快速連接建立:
- QUIC 支持 0-RTT(零往返時間)連接建立,這意味着在某些情況下,數據可以在連接建立的同時發送。這減少了初始連接建立的延遲。
5. HTTP各版本
HTTP 的每個版本都在解決其前任版本的不足,並適應不斷變化的網絡需求和技術進步。HTTP/1.1 增強了持久連接和緩存控制,HTTP/2 提升了傳輸效率和併發能力,而 HTTP/3 則通過 QUIC 協議提供了更快和更可靠的網絡傳輸體驗。
1. HTTP/0.9
- 發佈年份:1991
-
特點:
- 最初的 HTTP 版本,設計極為簡單。
- 僅支持 GET 方法,沒有版本號標識。
- 響應僅包含純文本數據,沒有 HTTP 頭部。
- 主要用於傳輸簡單的 HTML 頁面。
2. HTTP/1.0
- 發佈年份:1996 (RFC 1945)
-
特點:
- 引入了 HTTP 頭部,允許傳輸更多類型的數據。
- 支持多種方法:GET、POST、HEAD。
- 引入了狀態碼和響應頭,提供更多的響應信息。
- 每個請求/響應對使用一個單獨的 TCP 連接。
3. HTTP/1.1
- 發佈年份:1997 (RFC 2068),後續更新為 RFC 2616,並最終在 2014 年被 RFC 7230-7235 替代。
-
特點:
- 默認使用持久連接(Persistent Connection),減少了連接建立的開銷。
- 支持請求管道化(Pipelining),允許在同一個連接上發送多個請求而無需等待響應。
- 增強了緩存控制機制。
- 支持分塊傳輸編碼(Chunked Transfer Encoding),允許動態生成內容。
- 增加了更多的 HTTP 方法和頭字段。
4. HTTP/2
- 發佈年份:2015 (RFC 7540)
-
特點:
- 引入二進制分幀層,提升了傳輸效率。
- 支持多路複用,允許在一個連接上同時處理多個請求和響應。
- 使用 HPACK 壓縮算法對頭部進行壓縮,減少傳輸數據量。
- 支持服務器推送(Server Push),允許服務器主動向客户端發送資源。
5. HTTP/3
- 發佈年份:2022 (RFC 9114)
-
特點:
- 基於 QUIC 協議,運行在 UDP 之上,提供更快的連接建立和恢復能力。
- 解決了 TCP 層的隊頭阻塞問題,通過獨立流提供更好的性能。
- 繼續支持多路複用和服務器推送。
- 提供更好的安全性和加密性能。
前期的版本都是小版本迭代,有良好的兼容性,如:HTTP/1.0 -> HTTP/1.1。
但 HTTP/1.1 -> HTTP/2,HTTP/2 直接到 HTTP/3,都是大版本迭代,因為變更很大,向前兼容很難。另外市場上各家瀏覽器、社區生態對新版本的兼容也需要時間,所以主流的使用版本還是 HTTP/1.1。