HTTP/3來了!存續(xù)二十多年的TCP協(xié)議最終被拋棄!
6 月 6 日,IETF QUIC 和 HTTP 工作組成員 Robin Marx 宣布,經(jīng)過 5 年的努力,HTTP/3 被標(biāo)準(zhǔn)化為 RFC 9114,這是 HTTP 超文本傳輸協(xié)議的第三個(gè)主要版本。同時(shí),HTTP/2 也更新為 RFC 9113標(biāo)準(zhǔn),HTTP/1.1 和通用 HTTP 語義和緩存概念在 RFC 9110-9112 中也得到了加強(qiáng)。
TCP 是 Internet 上使用和部署最廣泛的協(xié)議之一,多年來一直被視為網(wǎng)絡(luò)基石,隨著HTTP/3正式被標(biāo)準(zhǔn)化,QUIC協(xié)議成功“上位”,UDP“取代”TCP成為基礎(chǔ)協(xié)議,TCP究竟“輸”在哪里?
?????
HTTP/3 采用了谷歌多年探索的基于 UDP 的 QUIC 協(xié)議,原名叫 HTTP-over-QUIC,在 2018 年被 IETF 批準(zhǔn)更名為 HTTP/3。目前,Cloudflare、Google Chrome、Firefox Nightly 均表示支持 HTTP/3。
為什么我們需要 HTTP/3?
很多人可能都會(huì)有這樣一個(gè)疑問,為什么在 2015 年才標(biāo)準(zhǔn)化了 HTTP/2 ,這么快就需要 HTTP/3?
事實(shí)上,我們并不是真的需要新的 HTTP 版本,而是需要對(duì)底層傳輸控制協(xié)議(TCP) 進(jìn)行升級(jí)。
TCP與HTTP的不解之緣
HTTP(超文本傳輸協(xié)議 1.0)的第一個(gè)正式版本在 1996 年完成。但是HTTP/1.0 沒有充分考慮分層代理、緩存、長(zhǎng)連接的需求和虛擬主機(jī)的影響。所以在一年后HTTP/1.1發(fā)布,這也是使用最廣泛的版本。
在 HTTP/1.1 中, 瀏覽器通過 TCP 連接一次只能下載一個(gè)文件, 如果一個(gè)頁(yè)面需要 10 個(gè) js 文件, 那么這些文件將會(huì)按順序下載。一個(gè)文件的延遲就會(huì)阻塞后面的其他內(nèi)容, 也就是我們常說的隊(duì)頭阻塞。
2015年, HTTP 協(xié)議迎來了更新, HTTP/2發(fā)布。HTTP/2 的一大特點(diǎn)是多路復(fù)用。引入了二進(jìn)制幀和流機(jī)制,允許使用單個(gè) TCP 連接, 通過 Stream 并行下載資源, 提高了傳輸效率。然而HTTP/2的多路復(fù)用技術(shù)使得多個(gè)請(qǐng)求其實(shí)是基于同一個(gè)TCP連接的,因此在HTTP/2中,TCP隊(duì)頭阻塞造成的影響會(huì)更大,如果某一個(gè)請(qǐng)求造成了TCP隊(duì)頭阻塞,那么多個(gè)請(qǐng)求都會(huì)受到影響。
事實(shí)上,在丟包率高的環(huán)境中,HTTP/1.1 性能更好。
此外,發(fā)起 HTTP 請(qǐng)求時(shí),需要經(jīng)過 TCP 三次握手和四次揮手的過程,整個(gè)過程共需要 3 個(gè) RTT 的時(shí)延才能發(fā)出請(qǐng)求數(shù)據(jù)。如果客戶端和服務(wù)器相距遙遠(yuǎn),則每RTT可能會(huì)花費(fèi)超過 100 毫秒,從而導(dǎo)致明顯的延遲。
RTT:往返時(shí)間(Round Trip Time),指一個(gè)請(qǐng)求從客戶端瀏覽器發(fā)送一個(gè)請(qǐng)求數(shù)據(jù)包到服務(wù)器,再?gòu)姆?wù)器得到響應(yīng)數(shù)據(jù)包的這段時(shí)間。RTT 是反映網(wǎng)絡(luò)性能的一個(gè)重要指標(biāo)。
?????
幾十年來,TCP 一直是網(wǎng)絡(luò)的基石,但種種問題讓大家不得不思考取代它的方法,這就是——QUIC,QUIC在幾個(gè)關(guān)鍵方面與 TCP 有很大不同,直接在其上運(yùn)行 HTTP/2 將非常困難。因此,HTTP/3 本身是對(duì) HTTP/2 的一個(gè)相對(duì)較小的改編,以使其與新的 QUIC 協(xié)議兼容。
?????
什么是QUIC協(xié)議
QUIC是一種通用、安全、多路復(fù)用的傳輸層新型網(wǎng)絡(luò)協(xié)議,它的目標(biāo)是取代TCP。
- 2012年,QUIC協(xié)議由當(dāng)時(shí)還在谷歌任職的Jim Roskind開發(fā)。
- 2013年,QUIC正式對(duì)外公布。
- 2015年,QUIC被提交給IETF進(jìn)行標(biāo)準(zhǔn)化。
但是直到六年以后,也就是2021年5月,IETF才發(fā)布了第一版標(biāo)準(zhǔn)化的QUIC,被命名為RFC 9000。同時(shí),IETF還發(fā)布使用了QUIC的HTTP/3標(biāo)準(zhǔn)化版本。QUIC吸納了很多與TCP類似的屬性,還有TLS加密,將它們置于UDP傳輸之上的應(yīng)用層中。
????
QUIC與 TCP 非常相似,除了 HTTP 和網(wǎng)頁(yè)加載之外,還可以將其用于許多用例。例如,DNS、SSH、SMB、RTP 等都可以在 QUIC 上運(yùn)行。
UDP+QUIC=最佳拍檔
UDP 是最基本的傳輸協(xié)議。除了端口號(hào)(例如,HTTP 使用端口 80,HTTPS 使用 443,DNS 使用端口 53)之外,它實(shí)際上不提供任何特性。它不通過握手建立連接,也不可靠:如果UDP包丟失,它不會(huì)自動(dòng)重傳。UDP 的“盡力而為”方法不保證可靠性,無需等待握手,也沒有 HoL 阻塞。在實(shí)踐中,UDP協(xié)議主要用于實(shí)時(shí)性要求很高,但不要求完整性的應(yīng)用,例如實(shí)時(shí)視頻會(huì)議或者游戲等。它對(duì)于需要較低的預(yù)先延遲的情況也很有用,例如,DNS域名查找只需要一個(gè)來回就可以完成。
在 UDP 之上,QUIC 結(jié)合了 TCP 數(shù)十年的部署和實(shí)踐經(jīng)驗(yàn),能夠?qū)崿F(xiàn)幾乎所有的 TCP的特性。QUIC 的傳輸是絕對(duì)可靠的,可以通過流量控制和擁塞控制機(jī)制來防止過載,并且以比 TCP 更智能、更高效的方式實(shí)現(xiàn)了這些功能。
QUIC 對(duì)于TCP 的改進(jìn)主要可歸結(jié)為四個(gè)方面:QUIC 與 TLS 深度集成、QUIC 支持多個(gè)獨(dú)立的字節(jié)流、QUIC 使用連接 ID、QUIC 使用幀(frame)。
QUIC 與 TLS 深度集成
TLS(傳輸層安全協(xié)議)負(fù)責(zé)保護(hù)和加密通過 Internet 發(fā)送的數(shù)據(jù)。當(dāng)使用 HTTPS 時(shí),純文本 HTTP 數(shù)據(jù)首先由 TLS 加密,然后由 TCP 傳輸。1.2 及更低版本的TLS通常需要兩次RTT,新版本的 TLS 1.3 只需一次RTT。
????
在互聯(lián)網(wǎng)早期,加密流量在處理方面的成本很高,因此很多情況下并不是必要的。TLS 是一個(gè)完全獨(dú)立的協(xié)議,可以選擇是否在 TCP 之上使用,這也是區(qū)分 HTTP(沒有TLS)和 HTTPS(有TLS)的原因。
隨著時(shí)間的推移,我們對(duì)互聯(lián)網(wǎng)安全的態(tài)度已經(jīng)轉(zhuǎn)變?yōu)椤澳J(rèn)安全”。因此QUIC的設(shè)計(jì)者選擇將加密深深地嵌入到 QUIC 本身中。雖然 TLS 1.3 仍然可以在 TCP 之上獨(dú)立運(yùn)行,但 QUIC 封裝了 TLS 1.3。換句話說,沒有 TLS 就無法使用 QUIC;QUIC(以及 HTTP/3)始終是完全加密的。此外,QUIC 還加密了幾乎所有的數(shù)據(jù)包頭字段。這為 QUIC 提供了幾個(gè)好處:
- QUIC 對(duì)用戶來說更安全:QUIC沒有辦法明文運(yùn)行,因此網(wǎng)絡(luò)攻擊者的選擇也更少。
- QUIC 的連接設(shè)置更快:雖然對(duì)于 TLS-over-TCP,兩種協(xié)議都需要各自單獨(dú)的握手,但 QUIC 將傳輸和加密握手合二為一,從而節(jié)省了一次往返時(shí)間。
- QUIC 更容易更新:如果在未來想為 QUIC 添加新功能,我們只必須更新終端設(shè)備,而不是所有的中間件。
QUIC 支持多個(gè)獨(dú)立的字節(jié)流
對(duì)于 HTTP/1.1,資源加載過程非常簡(jiǎn)單,因?yàn)槊總€(gè)文件都有自己的 TCP 連接。例如,如果我們有文件 A、B、C,我們將有三個(gè) TCP 連接。第一個(gè)將看到 AAAA 的字節(jié)流,第二個(gè) BBBB,第三個(gè) CCCC(每個(gè)字母重復(fù)都是一個(gè) TCP包)。這可行,但也非常低效,因?yàn)槊總€(gè)新的連接都會(huì)產(chǎn)生一些開銷。
HTTP/2 的主要目標(biāo)之一就是改善這種情況。HTTP/2 協(xié)議不再為每個(gè)文件打開一個(gè)新的 TCP 連接,而是通過單個(gè) TCP 連接下載不同的資源。這是通過多路復(fù)用不同的字節(jié)流來實(shí)現(xiàn)的。舉例來看,同樣是傳輸A、B、C三個(gè)文件,我們將獲得一個(gè) TCP 連接,傳入的數(shù)據(jù)形式可以是 AABBCCAABBCC等。通常情況下,使用HTTP/2 跟HTTP/1.1 一樣快或快一點(diǎn),但開銷要少得多。
????
HTTP/2的多路復(fù)用機(jī)制解決了HTTP層的隊(duì)頭阻塞問題,但是在TCP層仍然存在隊(duì)頭阻塞問題。
TCP協(xié)議在收到數(shù)據(jù)包之后,這部分?jǐn)?shù)據(jù)可能是亂序到達(dá)的,但是TCP必須將所有數(shù)據(jù)收集排序整合后給上層使用,如果其中某個(gè)包丟失了,就必須等待重傳,從而出現(xiàn)某個(gè)丟包數(shù)據(jù)阻塞整個(gè)連接的數(shù)據(jù)使用。例如,HTTP 級(jí)別的 AABBCCAABBCC,在TCP 眼里它只是 XXXXXXXXXXXX ,如果此時(shí)B丟失,它不會(huì)發(fā)現(xiàn)到底是誰丟失,而是整個(gè)重傳。
解決傳輸層的隊(duì)頭阻塞是 QUIC 的主要目標(biāo)之一。與 TCP 不同,QUIC 清楚地意識(shí)到它正在復(fù)用多個(gè)獨(dú)立的字節(jié)流。因此,QUIC 可以在每個(gè)流的基礎(chǔ)上執(zhí)行丟包檢測(cè)和恢復(fù)邏輯。
在上述場(chǎng)景中,QUIC 只會(huì)保留 B 的數(shù)據(jù),并且盡快將 A 和 C 的數(shù)據(jù)傳遞到 HTTP/3 層。
????
QUIC 使用連接 ID
一個(gè) TCP 連接是由四元組(源 IP 地址,源端口,目標(biāo) IP 地址,目標(biāo)端口)確定的,這意味著如果 IP 地址或者端口變動(dòng)了,就會(huì)導(dǎo)致需要 TCP 與 TLS 重新握手,這不利于移動(dòng)設(shè)備切換網(wǎng)絡(luò)的場(chǎng)景,比如 4G 網(wǎng)絡(luò)環(huán)境切換成 WIFI。這些問題都是 TCP 協(xié)議固有的問題。
????
為了解決這個(gè)問題,QUIC 引入了一個(gè)名為連接ID(connection identifier,CID)的新概念。每個(gè)連接在 4 元組之上分配了另一個(gè)編號(hào),該編號(hào)在兩個(gè)端點(diǎn)之間唯一標(biāo)識(shí)它。
????
更重要的是,因?yàn)檫@個(gè) CID 是在 QUIC 本身的傳輸層定義的,所以在網(wǎng)絡(luò)之間移動(dòng)時(shí)它不會(huì)改變。通過這種設(shè)置,即使 4 元組中的某一項(xiàng)發(fā)生了變化,QUIC 服務(wù)器和客戶端只需查看 CID即可知道它是同一個(gè)舊連接,可以繼續(xù)使用它。不需要重新握手,下載狀態(tài)可以保持原樣。這個(gè)功能通常稱為連接遷移。
QUIC 使用幀(frame)
與 TCP 不同,QUIC 不使用單個(gè)固定的數(shù)據(jù)包頭來發(fā)送所有協(xié)議元數(shù)據(jù)。相反,QUIC 具有短的數(shù)據(jù)包頭,并在數(shù)據(jù)包有效載荷內(nèi)使用各種“幀”來傳達(dá)額外信息。例如,一個(gè)ACK幀(用于確認(rèn))、一個(gè)NEW_CONNECTION_ID幀(用于幫助建立連接遷移)和一個(gè)STREAM幀(用于承載數(shù)據(jù)),如下圖所示:
????
這主要是一種優(yōu)化,因?yàn)椴皇敲總€(gè)包都攜帶所有可能的元數(shù)據(jù)(因此TCP包頭通常會(huì)浪費(fèi)相當(dāng)多的字節(jié))。使用幀還有一個(gè)好處,在未來將新幀類型定義為QUIC的擴(kuò)展將非常容易。例如,一個(gè)非常重要的框架是DATAGRAMframe,它允許通過加密的 QUIC 連接發(fā)送不可靠的數(shù)據(jù)。
總結(jié)
總的來說,QUIC相較于TCP有許多優(yōu)點(diǎn),但是想要真正實(shí)現(xiàn)全面推廣也是存在一些困難的。很多企業(yè)、運(yùn)營(yíng)商和組織對(duì)53端口(DNS)以外的UDP流量會(huì)進(jìn)行攔截或者限流(這些流量常被濫用于攻擊),因此基于UDP的QUIC協(xié)議的傳輸可能會(huì)受到屏蔽。此外,很多中間設(shè)備對(duì)于UDP的支持和優(yōu)化程度也并不高。
不過,盡管還存在一些未知的困難,但HTTP/3.0的時(shí)代一定會(huì)到來的!