HTTP/3 已經(jīng)來臨,這對 Web 性能是件大事。讓我們看看它能讓網(wǎng)站速度提升多少吧!
等等,HTTP/2 難道不好么?它在這幾年不是挺火的嗎?確實是,但它仍有一些問題。為了解決這些問題,新版本的協(xié)議正朝向“標(biāo)準(zhǔn)跟蹤(standards track,RFC 的類別之一)”做出努力。
嗯,但 HTTP/3 真能讓網(wǎng)絡(luò)變得更快?它肯定能,我們將用基準(zhǔn)測試來證明這一點。
預(yù)覽
在我們深入細(xì)節(jié)之前,讓我們快速預(yù)覽一下基準(zhǔn)測試的結(jié)果。在下方的圖表中,我們在相同的網(wǎng)絡(luò)中使用相同的瀏覽器請求相同的站點,唯一不同的只是 HTTP 協(xié)議的版本。每個站點都被重復(fù)請求 20 次,響應(yīng)時間通過瀏覽器的 Performance API 測量。(更多關(guān)于基準(zhǔn)測試的細(xì)節(jié)在下方。)
你可以清楚地看到使用每個新版本的 HTTP 協(xié)議(相較于 HTTP/1.1)帶來的性能提升:
當(dāng)?shù)乩砭嚯x更遠(yuǎn)或網(wǎng)絡(luò)不太可靠時,這些差別將變得更加明顯。
在了解 HTTP/3 基準(zhǔn)測試的細(xì)節(jié)之前,我們需要知道一些背景知識。
HTTP 簡史
HTTP(超文本傳輸協(xié)議 1.0)的第一個正式版本在 1996 年完成。然而,該版本存在一些實踐問題且部分標(biāo)準(zhǔn)需要更新,所以 HTTP/1.1 在一年后(也就是 1997 年)發(fā)布了。正如作者所說:
然而,HTTP/1.0 沒有充分考慮分層代理、緩存、持久連接的需求和虛擬主機的影響。此外,將自身標(biāo)榜為 "HTTP/1.0" 但又沒完全實踐 HTTP/1.0 的應(yīng)用數(shù)量急劇增加;因此,我們需要一個新版的協(xié)議以便兩個相互通信應(yīng)用能確認(rèn)對方真實的通信能力。
18 年后,新版本的 HTTP 發(fā)布了。在 2015 年,RFC 7540 大張旗鼓地宣布,會將 HTTP/2 標(biāo)準(zhǔn)化為協(xié)議的下一個主要版本。
一個連接,一個文件
如果一個網(wǎng)頁需要 10 個 JAVAScript 文件,那么瀏覽器就需要檢索所有的 10 個文件才能完成加載。在 HTTP/1.1 那個時代,一次與服務(wù)器的 TCP 連接只能下載一個文件。這意味著文件是依次下載的,只要有一個文件出現(xiàn)延遲,后面的所有下載都會被阻塞。這個現(xiàn)象被稱為隊頭阻塞;這對頁面性能是不利的。
為了解決這個問題,瀏覽器可以打開多個 TCP 連接來并行地檢索資源。然而,這是種資源密集型的方法。每個新的 TCP 連接都會消耗客戶端和服務(wù)端的資源;并且當(dāng)你再引入 TLS 后,整個通信過程將會發(fā)生大量的 SSL 協(xié)商。因此,我們需要一種更好的解決方案。
HTTP/2 中的多路復(fù)用
HTTP/2 的最大亮點就是它的多路復(fù)用(multiplexing)機制。HTTP/2 解決了應(yīng)用層的隊頭阻塞的問題,通過將為數(shù)據(jù)轉(zhuǎn)化為二進(jìn)制(譯者注:并且在傳輸前將數(shù)據(jù)進(jìn)行分幀,以幀為單位進(jìn)行傳輸),使得在多文件下載時能夠多路復(fù)用。即,客戶端可以同時請求所有的 10 個文件,并通過一個 TCP 連接并行地下載這 10 個文件。
不幸的是,HTTP/2 的通信過程中仍存在隊頭阻塞的問題,而源頭就出現(xiàn)在它的下一層 —— TCP 變成了傳輸鏈上最脆弱的一環(huán)。任何出現(xiàn)了丟包的數(shù)據(jù)流都需要等待該包重新傳輸后才能繼續(xù)。
然而,由于 HTTP/2 多路復(fù)用的并行特性對于 TCP 的丟包恢復(fù)機制是不可見的,一個丟失或順序不對的數(shù)據(jù)包會導(dǎo)致所有活動的事務(wù)停頓,無論其是否受到丟包的直接影響。
事實上,在高丟包的環(huán)境下,HTTP/1.1 反而表現(xiàn)得更好,正是因為 HTTP/2 開了太多并行的 TCP 連接!
QUIC 和 HTTP/3 中真正的多路復(fù)用
現(xiàn)在說到 HTTP/3。HTTP/2 和 HTTP/3 的主要區(qū)別在于所使用的傳輸協(xié)議。與之前的 TCP 協(xié)議不同,HTTP/3 使用了一個全新的協(xié)議 —— QUIC。QUIC 是一個通用的傳輸協(xié)議,解決了 HTTP/2 因為 TCP 而產(chǎn)生的隊頭阻塞問題。這個協(xié)議能讓你通過 UDP 創(chuàng)建一系列帶狀態(tài)的流(這與 TCP 很相似)。
QUIC 傳輸協(xié)議包含流的復(fù)用和對每個流的流量控制,這兩者與 HTTP/2 中實現(xiàn)的類似。通過在整個連接中提供流級別的可靠性和擁塞控制,比起 TCP 映射,QUIC 更能提高 HTTP 的性能。
如果你不關(guān)心測試是怎么進(jìn)行的,那就跳到下方的結(jié)果吧!
HTTP/3 的基準(zhǔn)測試
要想了解 HTTP/3 在性能方面帶來了什么改變,我們需要先搭建一個基準(zhǔn)測試環(huán)境。
html
為了能更貼合實際使用情況,這次的測試考慮了三種場景 —— 一個小型站點、一個內(nèi)容站點(大量圖片和些許 JavaScript 資源)和一個單頁面應(yīng)用(大量 JavaScript 資源)。我查看了幾個現(xiàn)實生活中的站點,并計算了每個站點的圖片和 JavaScript 文件的平均數(shù)量,然后編寫了一些與這些資源數(shù)量(和大小)差不多的的演示站點。
- 小型站點
- 10 個 2 kB 到 100 kB 的 JavaScript 文件;
- 10 張 1kB 到 50 kB 的圖片;
- 總載荷大小 600 kB,共計 20 個阻塞資源。
- 內(nèi)容站點
- 50 個 2 kB 到 1 MB 的 JavaScript 文件;
- 55 張 1 kB 到 1 MB 的圖片;
- 總載荷大小 10MB,共計 105 個阻塞資源(在開發(fā)者工具中看看 cnn.com 你就會明白這個量為什么會這么大了)。
- 單頁面應(yīng)用
- 85 個 2 kB 到 1 MB 的 JavaScript 文件;
- 30 張 1 kB 到 50 kB 的圖片;
- 總載荷大小 15MB,共計 115 個阻塞資源(在開發(fā)者工具中看看 JIRA (缺陷跟蹤管理系統(tǒng))吧)。
服務(wù)端
Caddy 作為這次測試的服務(wù)器,向外提供資源及 HTML。
- 所有響應(yīng)都使用 Cache-Control: "no-store" 以確保瀏覽器每次都會重新下載資源;
- HTTP/1.1 和 HTTP/2 使用 TLS 1.2;
- HTTP/3 使用 TLS 1.3;
- 所有的 HTTP/3 連接都開啟 0-RTT。
地理位置
測試是從我在明尼蘇達(dá)州的計算機到三個獨立數(shù)據(jù)中心(由 Digital Ocean 托管)進(jìn)行的:
- 美國紐約
- 英國倫敦
- 印度班加羅爾
客戶端
瀏覽器將連續(xù)請求同一個頁面 20 次,每次請求間隔 3 秒,過程完全自動化。網(wǎng)絡(luò)的額定速度為 200 Mbps。數(shù)據(jù)采集時,計算機上沒有運行其他應(yīng)用程序。
HTTP/3 有多快?
美國紐約
以下是從紐約數(shù)據(jù)中心請求三個不同站點時 HTTP/2 與 HTTP/3 的響應(yīng)時間:
HTTP/3 在:
- 小型站點快了 200 毫秒
- 內(nèi)容站點快了 325 毫秒
- 單頁面應(yīng)用快了 300 毫秒
明尼蘇達(dá)州距離紐約 1000 英里(約等于 160 公里);這長度對于網(wǎng)絡(luò)連接來說不算什么。然而重要的是,即使在相對較短的距離內(nèi),HTTP/3 也能夠?qū)⑿阅芴岣哌@么多。
英國倫敦
在這次的測試中,我也包含了 HTTP/1.1 的基準(zhǔn)測試。為了展示 HTTP/2 和 HTTP/3 快了多少,我將下方圖表的軸刻度都保持一致了。你可以看到,對于內(nèi)容站點,HTTP/1.1 的速度是多么的慢;慢得連圖表都不能完全顯示!
正如你所見,當(dāng)網(wǎng)絡(luò)的距離更遠(yuǎn)時,速度的提高更明顯了。
- 小型站點快了 600 毫秒(速度是紐約的 3 倍)
- 內(nèi)容站點快了 1200 毫秒(速度是紐約的 3.5 倍)
- 單頁面應(yīng)用快了 1000 毫秒(速度是紐約的 3 倍)
印度班加羅爾
HTTP/3 性能的進(jìn)步在從印度加載頁面時最為明顯。我并不打算測試 HTTP/1.1,因為它太慢了。以下是 HTTP/2 與 HTTP/3 的結(jié)果對比:
當(dāng)請求涉及更大的地理區(qū)域和更多的網(wǎng)絡(luò)躍點時,HTTP/3 仍然繼續(xù)領(lǐng)先。更值得注意的是 HTTP/3 的響應(yīng)時間數(shù)據(jù)分布是多么的集中(譯者注:這說明在保證快的前提下,HTTP/3也很穩(wěn)定)。當(dāng)數(shù)據(jù)包傳輸數(shù)千英里時,QUIC 將發(fā)揮重要的作用。
在每種情況下 HTTP/3 都比歷代 HTTP 更快!
為什么 HTTP/3 這么快?
真正的多路復(fù)用
HTTP/3 真正的多路復(fù)用特性意味著堆棧上的任何地方都不會發(fā)生隊頭阻塞。當(dāng)你從更遠(yuǎn)的地理位置請求資源時,丟包的可能性會高出很多,TCP 重新傳輸?shù)男枨笠矔岣摺?/p>
顛覆局面的 0-RTT
此外,HTTP/3 也支持 0-RTT QUIC 連接,減少了建立安全 TLS 連接的數(shù)據(jù)往返次數(shù)。
QUIC 中的 0-RTT 功能能讓客戶端在三次握手完成之前發(fā)送應(yīng)用數(shù)據(jù)。這個功能通過重用先前連接的參數(shù)實現(xiàn)。0-RTT 依賴于客戶端記住的重要參數(shù),并向服務(wù)器提供 TLS 會話票證(session ticket)以恢復(fù)相同的信息。
然而,你不應(yīng)該盲目地啟用 0-RTT。基于你的威脅模型,它可能存在一些安全問題。
0-RTT 數(shù)據(jù)的安全屬性弱于其他類型的 TLS 數(shù)據(jù)。具體來說:
數(shù)據(jù)不是前向保密(forward secret)的;數(shù)據(jù)僅僅只被預(yù)共享密鑰(pre-shared key,PSK)衍生的密鑰加密。 不能保證連接之間不重放(譯者注:詳情見重放攻擊)。
我現(xiàn)在能用 HTTP/3 了嗎?
或許可以喔!雖然協(xié)議現(xiàn)在仍處于互聯(lián)網(wǎng)草案(Internet-Draft)狀態(tài),但市面上已有許多不同的實踐方案了。
作為這次的基準(zhǔn)測試,我特別選擇了 Caddy。我只需要修改 Caddyfile 中的一個簡單的配置就能啟用 HTTP/3。
Nginx 對 HTTP/3 也有實驗性的支持,且正在朝向?qū)l(fā)布的 HTTP/3(它就在不久的將來)邁進(jìn)。
像是谷歌和 Facebook 這些科技巨擘已經(jīng)通過 HTTP/3 提供服務(wù)了。在現(xiàn)代瀏覽器中,google.com 已完全使用 HTTP/3。
對于那些“困在”微軟生態(tài)系統(tǒng)中的用戶,據(jù)說 windows Server 2022 將會支持 HTTP/3,但你需要執(zhí)行一些“深奧”的步驟來啟用它。
總結(jié)
HTTP/3 能在用戶體驗方面帶來了很大的改善。在一般情況下,站點需要的資源越多,HTTP/3 和 QUIC 的性能提升就越大。隨著標(biāo)準(zhǔn)離定稿越來越近,也許你是時候該考慮為你的網(wǎng)站啟用 HTTP/3 了。
作者:披著狼皮的羊_
鏈接:
https://juejin.cn/post/7055178022445383694
來源:稀土掘金