天天看點

從 HTTP/1.1 到 HTTP/3

從 HTTP/1.1 到 HTTP/3,解決了一些舊協定的問題,引入了好用的新功能。

HTTP/1.1

HTTP/1.1 通過在傳輸層和應用層之間增加 SSL/TSL 解決資料不安全的問題,但它本身還有一些其它的不足。

  • 同一時間,一個連接配接隻能對應一個請求,針對同一個域名,大多數浏覽器允許同時最多6個并發請求
  • 隻允許用戶端主動發起請求,一個請求隻能對應一個響應
  • 同一個會話的多次請求中,頭資訊會被重複傳輸

針對于以上情況,增加了新的協定 SPDY。

SPDY

SPDY(speedy的縮寫),是基于 TCP 的應用層協定,它強制要求使用 SSL/TLS,SPDY 并不用于取代 HTTP,它隻是修改了 HTTP 請求與響應的傳輸方式,隻需增加一個 SPDY 層,現有的所有服務端應用均不用做任何修改,SPDY 是 HTTP/2 的前身。

從 HTTP/1.1 到 HTTP/3

HTTP/2

HTTP/2(類似于HTTP+SPDY,不強制使用SSL,但大部分都會使用SSL)在底層傳輸做了很多的改進和優化,但在語意上完全與HTTP/1.1相容,比如請求方法(如GET、POST)、Status Code、各種Headers等都沒有改變。

超快的加載速度

在 HTTP/2測速網站中,可以看到 HTTP/2 和 HTTP/1.1 對比170張32*48像素的小圖組合成的大圖加載速度的時長對比。那為什麼會存在如此大的差異呢,在于HTTP/2在很多方面做了調整。

從 HTTP/1.1 到 HTTP/3

二進制格式

首先就是 HTTP/2 采用二進制格式傳輸資料,而非 HTTP/1.1 的文本格式。

從 HTTP/1.1 到 HTTP/3

多路複用

新的二進制分幀機制改變了用戶端與伺服器之間互動資料的方式,這裡有幾個新的概念。

• 流:已建立的連接配接上的雙向位元組流。

• 消息:與邏輯消息對應的完整的一系列資料幀。

• 幀:HTTP 2.0 通信的最小機關,每個幀包含幀首部,至少也會辨別出目前幀所屬的流

每個資料流以消息的形式發送,而消息由一或多個幀組成,這些幀可以亂序發送,然後再根據每個幀首部的流辨別符重新組裝。

從 HTTP/1.1 到 HTTP/3

圖中包含了同一個連接配接上多個傳輸中的資料流:用戶端正在向伺服器傳輸一個 DATA 幀(stream 5),與此同時,伺服器正向用戶端亂序發送 stream 1 和 stream 3 的一系列幀。此時,一個連接配接上有 3 個請求 / 響應并行交換。

把 HTTP 消息分解為獨立的幀,交錯發送,然後在另一端重新組裝是 HTTP 2.0 重要的一項增強。事實上,這個機制會在整個 Web 技術棧中引發一系列連鎖反應, 進而帶來巨大的性能提升。

• 并行交錯地發送請求,請求之間互不影響

• 并行交錯地發送響應,響應之間互不幹擾

• 隻使用一個連接配接即可并行發送多個請求和響應

• 消除不必要的延遲,進而減少頁面加載的時間

• 不必再為繞過 HTTP 1.x 連接配接限制而多做很多工作(如image sprites、合并CSS\JS、内嵌CSS\JS\Base64圖檔、域名分片)

首部壓縮

HTTP 的每一次通信都會攜帶一組首部,用于描述傳輸的資源及其屬性。在 HTTP 1.x 中,這些中繼資料都是以純文字形式發送的,通常會給每個請求增加 500~800 字 節的負荷。如果算上 HTTP cookie,增加的負荷通常會達到上千位元組。為減少這些開銷并提升性能,HTTP 2.0 會壓縮首部中繼資料。

從 HTTP/1.1 到 HTTP/3

用戶端和伺服器緩存上一次的請求,隻發不同的請求頭,靜态表儲存着常用請求頭,動态表是随着新的請求增加新的請求頭,用戶端和伺服器同步儲存兩張表,一個頭資訊對應着一個索引,如果請求頭存在于索引表中,隻需發索引号。

伺服器推送

HTTP1 中隻允許用戶端主動發起請求,一個請求隻能對應一個響應,HTTP 2.0 新增的一個新功能,就是伺服器可以對一個用戶端請求發送多個響應。除了對最初請求的響應外,伺服器還可以額外向用戶端推送資源,而無需用戶端明确地請求。

從 HTTP/1.1 到 HTTP/3

Web應用可能存在幾十個資源,如果伺服器能主動的推送資源給伺服器,用戶端就不需要分析伺服器提供的文檔再逐個查找,能減少額外的時間延遲。伺服器推送功能在網頁中嵌入的CSS、JavaScript 或者嵌入其它資源有應用到。

并且還帶來了這些好處

  • 用戶端可以緩存推送過來的資源
  • 用戶端可以拒絕推送過來的資源
  • 推送資源可以由不同的頁面共享
  • 伺服器可以按照優先級推送資源

以上都是 HTTP/2 提供的新特性,以解決 HTTP1 的不足,但它自身也存在一些問題。

隊頭阻塞

請求中如果丢失了一個包,導緻後面的請求阻塞,此時會等待丢失的包重發,這是TCP底層決定的。

從 HTTP/1.1 到 HTTP/3

握手延遲

HTTP2的傳輸層協定還是使用的TCP,仍然有握手的環節。

RTT(Round Trip Time):往返時延,可以簡單了解為通信一來一回的時間,建立連接配接 一個RTT約100ms 還加上TLS 握手要300ms,仍然需要不少時間。

從 HTTP/1.1 到 HTTP/3

HTTP/3

為了解決以上問題,于是就有了 HTTP/3,HTTP/3 由 Google 開發,棄用 TCP協定,改為使用基于 UDP 協定的 QUIC 協定實作。

從 HTTP/1.1 到 HTTP/3

解決隊頭阻塞

QUIC協定使用的 UDP 協定,直接扔無序的資料過來就行,無需排隊等待請求的響應,就不存在隊頭阻塞的問題。

從 HTTP/1.1 到 HTTP/3

解決握手延遲

而 UDP 連接配接無需 “握手”,也就沒有 “握手延遲” 的問題。

從 HTTP/1.1 到 HTTP/3

存疑

1、UDP 無需建立連接配接,如何來保證 “可靠傳輸” 呢?

UDP 接收資料包,如果丢失也不會重新傳遞,直接對接應用層 HTTP 協定的話,資料可能不完整,這裡在應用層和傳輸層中還增加了 QUIC 協定,如果丢失了包,會告知對方的 QUIC 層,重新傳輸丢失的包。也就是說由QUIC來保證"可靠傳輸",相當于實作了TCP的功能。

2、為何Google不開發一個新的不同于TCP、UDP的傳輸層協定?

目前世界上的網絡裝置基本隻認TCP、UDP,如果要修改傳輸層,意味着作業系統的核心也要修改,另外,許多TCP新特性都因缺乏廣泛支援而沒有得到廣泛的部署或使用,是以,要想開發并應用一個新的傳輸層協定,是極其困難的一件事情。

連接配接遷移

TCP 基于4要素(源IP、源端口、目标IP、目标端口),切換網絡時至少會有一個要素發生變化,導緻連接配接發生變化,當連接配接發生變化時,如果還使用原來的TCP連接配接,則會導緻連接配接失敗,就得等原來的連接配接逾時後重建立立連接配接。

是以我們有時候發現切換到一個新網絡時,即使新網絡狀況良好,但内容還是需要加載很久(可能會出現網絡異常的情況)。

QUIC的連接配接不受4要素的影響,當4要素發生變化時,原連接配接依然維持,QUIC連接配接不以4要素作為辨別,而是使用一組Connection ID(連接配接ID)來辨別一個連接配接,即使IP或者端口發生變化,隻要Connection ID沒有變化,那麼連接配接依然可以維持,當裝置連接配接到Wi-Fi時,将進行中的下載下傳從蜂窩網絡連接配接轉移到更快速的Wi-Fi連接配接,當Wi-Fi連接配接不再可用時,将連接配接轉移到蜂窩網絡連接配接。

總結

  • HTTP/1 存在請求數量受限、伺服器無法主動推送消息、頭部資訊過多的問題
  • HTTP/2 增加二進制資料、多路複用、首部壓縮、伺服器推送的功能,存在隊頭阻塞、握手延遲的問題
  • HTTP/3 使用基于 UDP 協定的 QUIC 協定實作,解決隊頭阻塞、握手延遲的問題,增加連接配接遷移的特性

以上就是HTTP/2,HTTP/3的相關介紹。更多有關

前端

網絡協定

的内容可以參考我其它的博文,持續更新中~

參考文獻:《Web性能權威指南》

參考視訊:《網絡協定從入門到底層原理》