HTTP 3的前世今生及嘗鮮
HTTP/3又迎來(lái)一個(gè)里程碑:近日Cloudflare官方宣其邊緣網(wǎng)絡(luò)上已全面提供QUIC和HTTP/3支持。那么HTTP/3可以帶來(lái)哪些變化和優(yōu)勢(shì)呢? 對(duì)Internet的用戶,并且通過(guò)瀏覽器和其他客戶端與站點(diǎn)進(jìn)行高效交互??赏ㄟ^(guò)使用最新Chrome Canary瀏覽器以HTTP/3 UDB協(xié)議和服務(wù)器交互,對(duì)于使用命令行客戶端的人,最新版本的curl也提供了對(duì)HTTP/3的支持。本文蟲(chóng)蟲(chóng)將介紹HTTP/3的發(fā)展歷程,以及用戶如何啟用HTTP 3,如何通過(guò)瀏覽器Chrome及命令行客戶端curl使用HTTP 3。
HTTP發(fā)展歷程
首先,我們先來(lái)介紹下HTTP多年來(lái)的發(fā)展,以便更好地理解HTTP/3。
HTTP/1.0
HTTP協(xié)議源于1996年,在這一年發(fā)布了HTTP/1.0規(guī)范(0.x版本忽略),該規(guī)范定義了我們今天常見(jiàn)的基本HTTP文本規(guī)格定義。在HTTP/1.0中定義了客戶端和服務(wù)器之間的每個(gè)請(qǐng)求/響應(yīng)交換都要?jiǎng)?chuàng)建一個(gè)新的TCP連接,所以在進(jìn)行每個(gè)請(qǐng)求均需大家熟知的"三次握手,四次揮手"的歷程,因此請(qǐng)求難免會(huì)產(chǎn)生延遲。比如一個(gè)典型的HTTP/TLS過(guò)程,圖解如下:

而且,為了避免將無(wú)法處理的數(shù)據(jù)包泛洪到網(wǎng)絡(luò)中,TCP協(xié)議對(duì)建立的連接使用使用了一種稱為"慢啟動(dòng)"的預(yù)熱暫緩期用來(lái)給TCP堵塞控制算法確定可以傳輸?shù)臄?shù)據(jù)量,而不是在建立連接后盡快發(fā)送所有未完成的數(shù)據(jù)。由于每一個(gè)新連接都必須經(jīng)過(guò)這個(gè)緩慢的啟動(dòng)過(guò)程,這也成了網(wǎng)絡(luò)性能的一個(gè)瓶頸。
HTTP/1.1 keep-alive
隨之而來(lái)的的HTTP/1.1版本中引入"keep-alive(保活)"連接的方法來(lái)解決這些問(wèn)題。通過(guò)保活技術(shù),可以讓客戶端重用TCP連接,而不需要每次都重新建立TCP連接,從而解決初始連接建立和緩慢連接的問(wèn)題。但這并不能從實(shí)質(zhì)上解決問(wèn)題,盡管多個(gè)請(qǐng)求可以共享同一個(gè)連接,但是仍然必須一個(gè)接一個(gè)地序列化它們,因此客戶端和服務(wù)器只能在任何給定時(shí)間為每個(gè)連接執(zhí)行一次請(qǐng)求/響應(yīng)交換。
隨著網(wǎng)絡(luò)和Web技術(shù)的發(fā)展,每個(gè)網(wǎng)站所需的資源(CSS,JS腳本,圖片,視頻等)的增加,瀏覽器在獲取和渲染呈現(xiàn)網(wǎng)頁(yè)時(shí)對(duì)并發(fā)性的需要越來(lái)越迫切。但是,由于HTTP/1.1只允許客戶端每次只能進(jìn)行一個(gè)HTTP請(qǐng)求/響應(yīng)交換,因此在網(wǎng)絡(luò)層上獲得并發(fā)性的唯一方法是并行使用多個(gè)TCP連接,這樣一來(lái)就無(wú)法享受?;罴夹g(shù)帶來(lái)的好處。
HTTP/2 SPDY
又過(guò)了十多年后,出現(xiàn)了SPDY,然后是HTTP/2規(guī)范。它首先引入了HTTP流的概念。通抽象HTTP實(shí)現(xiàn)將不同的HTTP交換并發(fā)地復(fù)用到同一個(gè)TCP連接上,瀏覽器可以更有效地重用TCP連接。

HTTP/2解決了單個(gè)TCP連接的使用效率低的問(wèn)題,可以通過(guò)同一連接同時(shí)傳輸多個(gè)請(qǐng)求/響應(yīng)。但是如果傳輸中發(fā)生數(shù)據(jù)丟包,即使丟失的數(shù)據(jù)僅涉及單個(gè)請(qǐng)求,所有請(qǐng)求和響應(yīng)也同樣會(huì)受到數(shù)據(jù)包丟失的影響而需要重傳。因?yàn)楸M管HTTP/2可以在不同的流上隔離不同的HTTP交換,但是底層的TCP并無(wú)法對(duì)他們進(jìn)行區(qū)別,TCP能看到的只是沒(méi)有任何標(biāo)志的字節(jié)流。
TCP的作用是以正確的順序從一個(gè)端點(diǎn)到另一端點(diǎn)傳遞整個(gè)字節(jié)流。當(dāng)承載某些字節(jié)的TCP數(shù)據(jù)包在網(wǎng)絡(luò)路徑上丟失時(shí),它將在流中造成間隙,并且TCP需要在檢測(cè)到丟失時(shí)通過(guò)重新發(fā)送受影響的數(shù)據(jù)包來(lái)填充它。這樣即使丟失此后沒(méi)有丟失并且屬于完全獨(dú)立的HTTP請(qǐng)求,也不能將數(shù)據(jù)包后的已成功傳輸?shù)臄?shù)據(jù)包傳遞給應(yīng)用層。因此,最終會(huì)導(dǎo)致他們也會(huì)產(chǎn)生不必要的延遲。這個(gè)問(wèn)題被稱為TCP head-of-line blocking (TCP隊(duì)頭阻塞)。

為了解決隊(duì)頭阻塞問(wèn)題,HTTP/2中也引入了多路復(fù)用(Multiplexing)技術(shù),將TCP流可以傳輸?shù)臄?shù)據(jù)分為若干消息,每個(gè)消息再劃分為最小的二進(jìn)制幀組成,這樣即使一個(gè)請(qǐng)求被阻塞了,也不會(huì)影響其他請(qǐng)求,如上圖中第四種情況所示。
HTTP/3 QUIC
當(dāng)然這些改良TCP的方案都只能部分解決問(wèn)題,為了徹底從根解決問(wèn)題。那就需要徹底更換底層的TCP協(xié)議,這就是谷歌多年探索的基于UDP的QUIC協(xié)議,這也是HTTP/3的基礎(chǔ)。QUIC協(xié)議中在傳輸層將數(shù)據(jù)流作為基本,QUIC流共享相同的QUIC連接,需要額外的握手和慢啟動(dòng)來(lái)創(chuàng)建新的QUIC流,通過(guò)底層使用UDP協(xié)議以及將QUIC數(shù)據(jù)包封裝在UDP數(shù)據(jù)報(bào)的頂部,實(shí)現(xiàn)QUIC流的獨(dú)立交付。因此在大多數(shù)情況下,影響一個(gè)流的丟包不會(huì)影響其他流。
與TCP相比,使用UDP可以提供更大的靈活性,并且可以使QUIC實(shí)現(xiàn)完全存在于用戶空間中。協(xié)議實(shí)現(xiàn)的更新不再依賴于操作系統(tǒng)更新。借助QUIC,可以將HTTP級(jí)別的流簡(jiǎn)單地映射為QUIC流的頭,從而繼承HTTP/2的所有好處,而不會(huì)產(chǎn)生隊(duì)頭阻塞問(wèn)題。

QUIC還結(jié)合了典型的3次TCP握手和TLS 1.3的握手。這樣默認(rèn)情況就可以提供加密和身份驗(yàn)證,并且加速連接的建立。就算HTTP會(huì)話中的初始請(qǐng)求需要新的QUIC連接,在數(shù)據(jù)開(kāi)始流動(dòng)之前所引起的等待時(shí)間也較低。

HTTP/3的使用
HTTP/3和QUIC給我們帶來(lái)開(kāi)天辟地的變化,可以從根本上解決HTTP標(biāo)準(zhǔn)許久以來(lái)的許多問(wèn)題和缺陷。那么我們?nèi)绾瘟⒖淌褂盟鼛?lái)的福利呢?
quiche框架
為了支持推廣HTTP/3 Cloudflare使用Rust開(kāi)發(fā)并開(kāi)源一個(gè)HTTP/3和QUI的應(yīng)用框架,而且還給該應(yīng)用使用一個(gè)非??刹偷拿謖uiche(乳蛋餅)和logo,估計(jì)以借此吸引人們盡快品嘗HTTP/3制成的美食。

quiche的源碼托管在github上(github:/cloudflare/quiche),在clone源碼后,可以通過(guò)cargo編譯(注意需要rust 1.38及更新的版本,BoringSSL及其windows版本NASM):
- cargo build -examples
quiche也提供了以docker為基礎(chǔ)的實(shí)驗(yàn)環(huán)境包括http3-client, http3-server, 客戶端和服務(wù)器端,使用方法如下:
docker編譯:
- docker build -t cloudflare-quiche .
進(jìn)行HTTP/3請(qǐng)求
- docker run -it cloudflare-quiche http3-client Url
網(wǎng)站啟用
目前Cloudflare的選擇性開(kāi)部分放客戶如已經(jīng)可以通過(guò)簡(jiǎn)單手動(dòng)設(shè)置啟用HTTP/3功能,方法是在Cloudflare儀表板,手動(dòng)在"網(wǎng)絡(luò)"選項(xiàng)卡開(kāi)啟開(kāi)關(guān):

客戶端使用
目前知名瀏覽器谷歌Chrome和Firefox都已經(jīng)實(shí)驗(yàn)性提供對(duì)HTTP/3的支持。Chrome在Canary,F(xiàn)irefox將在Nightly正式正式提供支持。

Chrome瀏覽器:首先需要下載并安裝最新的Canary版本。然后,通過(guò)設(shè)置以下命令行參數(shù)啟動(dòng)Chrome Canary:
- "--enable-quic"和" --quic-version = h3-23"
然后就可以支持HTTP/3,可以通過(guò)Chrome開(kāi)發(fā)人員工具中的"網(wǎng)絡(luò)"標(biāo)簽頁(yè)來(lái)檢查使用的協(xié)議版本:

注意到協(xié)議類型為"http2+quic/99",這就是表示Http3。
使用curl
curl最新版7.66,也添加了對(duì)HTTP/3的實(shí)驗(yàn)性支持。我們可以下載編譯試用,在此前蟲(chóng)蟲(chóng)文章中對(duì)此介紹過(guò)。
要使用HTTP/3需要使用新添加的 "--http3"標(biāo)志來(lái)進(jìn)行請(qǐng)求:
- curl -I URL --http3
