HTTP 3.0之QUIC優(yōu)勢和TCP弊端

1 HTTP 3.0

1.1 簡介

1.1.1 引言

HTTP/1.1HTTP/2狡相,HTTP 協(xié)議一直都是使用 TCP 作為傳輸協(xié)議定铜。
然而伞芹,就在最新的 HTTP/3幌甘,HTTP 就直接把 TCP 拋棄了蔚万,向孤立無援的 UDP 伸出了援手驴剔,基于 UDP 協(xié)議的基礎(chǔ)上届巩,在應(yīng)用層實(shí)現(xiàn)了一個(gè)可靠的傳輸協(xié)議 —— QUIC旱易。

23700d0d553bd21acdd527c8b8e9e168_78e6bad99f544fd98b8d57a939b07690.png

很多同學(xué)可能就好奇了峦朗,HTTP 都用 TCP 都用了幾十年了建丧,而且 TCP 已經(jīng)是那么完善的可靠傳輸協(xié)議了,又有超時(shí)重傳波势、按序接收翎朱、流量控制、擁塞控制這些特性尺铣,怎么突然就把 TCP 拋棄了拴曲?到底是 TCP 哪里做的不夠好?

1.1.2 QUIC 協(xié)議概覽

QUIC (Quick UDP Internet Connections, 快速UDP網(wǎng)絡(luò)連接)是基于UDP的協(xié)議, 利用了UDP的速度和效率, 同時(shí)整合TCP, TLSHTTP/2的優(yōu)點(diǎn)并加以優(yōu)化. 用一張圖可以清晰的表示他們之間的關(guān)系.

image.png

QUIC是用來替代TCP, SSL/TLS的傳輸層協(xié)議, 在傳輸層之上還有應(yīng)用層
我們熟知的應(yīng)用層協(xié)議有HTTP, FTP, IMAP等, 這些協(xié)議理論上都可以運(yùn)行在QUIC上, 其中運(yùn)行在QUIC之上的協(xié)議被稱為HTTP/3凛忿, 這就是HTTP over QUICHTTP/3的含義

1.2 隊(duì)頭阻塞/多路復(fù)用問題

HTTP/1.1HTTP/2都存在隊(duì)頭阻塞的問題(Head Of Line blocking)

TCP是個(gè)面向連接的協(xié)議, 即發(fā)送請(qǐng)求后需要收到ACK消息, 以確認(rèn)對(duì)象已接受數(shù)據(jù). 如果每次請(qǐng)求都要在收到上次請(qǐng)求的ACK消息后再請(qǐng)求, 那么效率無疑很低. 后來HTTP/1.1提出了Pipeline技術(shù), 允許一個(gè)TCP連接同時(shí)發(fā)送多個(gè)請(qǐng)求. 這樣就提升了傳輸效率.

在這樣的背景下, 隊(duì)頭阻塞發(fā)生了. 比如, 一個(gè)TCP連接同時(shí)傳輸10個(gè)請(qǐng)求, 其中1,2,3個(gè)請(qǐng)求給客戶端接收, 但是第四個(gè)請(qǐng)求丟失, 那么后面第5-10個(gè)請(qǐng)求都被阻塞. 需要等第四個(gè)請(qǐng)求處理完畢后才能被處理. 這樣就浪費(fèi)了帶寬資源.

因此, HTTP一般又允許每個(gè)主機(jī)建立6個(gè)TCP連接, 這樣可以更加充分的利用帶寬資源, 但每個(gè)連接中隊(duì)頭阻塞的問題還是存在的.

TCP 隊(duì)頭阻塞的問題要從兩個(gè)角度看澈灼,一個(gè)是發(fā)送窗口的隊(duì)頭阻塞,另外一個(gè)是接收窗口的隊(duì)頭阻塞

1.2.1 發(fā)送窗口的隊(duì)頭阻塞

TCP 發(fā)送出去的數(shù)據(jù)店溢,都是需要按序確認(rèn)的叁熔,只有在數(shù)據(jù)都被按順序確認(rèn)完后,發(fā)送窗口才會(huì)往前滑動(dòng)床牧。舉個(gè)例子荣回,比如下圖的發(fā)送方把發(fā)送窗口內(nèi)的數(shù)據(jù)全部都發(fā)出去了,可用窗口的大小就為 0 了戈咳,表明可用窗口耗盡心软,在沒收到 ACK 確認(rèn)之前是無法繼續(xù)發(fā)送數(shù)據(jù)了革砸。

1cc51ff9e241c9dc0e0c6674a959d5c4_17003aec36db41259a2b47a37a35ff82.png

接著,當(dāng)發(fā)送方收到對(duì)第 32~36 字節(jié)的 ACK 確認(rèn)應(yīng)答后糯累,則滑動(dòng)窗口往左邊移動(dòng) 5 個(gè)字節(jié)算利,因?yàn)橛?5 個(gè)字節(jié)的數(shù)據(jù)被應(yīng)答確認(rèn),接下來第 52~56 字節(jié)又變成了可用窗口泳姐,那么后續(xù)也就可以發(fā)送 52~56 這 5 個(gè)字節(jié)的數(shù)據(jù)了效拭。

8edcaab35ef3b35633e52d50228ff1da_0def85d07e4b40fb87ca8edfff814cad.png

但是如果某個(gè)數(shù)據(jù)報(bào)文丟失或者其對(duì)應(yīng)的 ACK 報(bào)文在網(wǎng)絡(luò)中丟失,會(huì)導(dǎo)致發(fā)送方無法移動(dòng)發(fā)送窗口胖秒,這時(shí)就無法再發(fā)送新的數(shù)據(jù)缎患,只能超時(shí)重傳這個(gè)數(shù)據(jù)報(bào)文,直到收到這個(gè)重傳報(bào)文的 ACK阎肝,發(fā)送窗口才會(huì)移動(dòng)挤渔,繼續(xù)后面的發(fā)送行為。

舉個(gè)例子风题,比如下圖判导,客戶端是發(fā)送方,服務(wù)器是接收方


879a677046eaf46e858fddb3c827290d_09d0b3418b9745f18a91a97e0f37cb47.png

客戶端發(fā)送了第 5~9 字節(jié)的數(shù)據(jù)沛硅,但是第 5 字節(jié)的 ACK 確認(rèn)報(bào)文在網(wǎng)絡(luò)中丟失了眼刃,那么即使客戶端收到第 6~9 字節(jié)的 ACK 確認(rèn)報(bào)文,發(fā)送窗口也不會(huì)往前移動(dòng)摇肌。

此時(shí)的第 5 字節(jié)相當(dāng)于隊(duì)頭擂红,因?yàn)闆]有收到隊(duì)頭ACK 確認(rèn)報(bào)文,導(dǎo)致發(fā)送窗口無法往前移動(dòng)围小,此時(shí)發(fā)送方就無法繼續(xù)發(fā)送后面的數(shù)據(jù)昵骤,相當(dāng)于按下了發(fā)送行為的暫停鍵,這就是發(fā)送窗口的隊(duì)頭阻塞問題

1.2.2 接收窗口的隊(duì)頭阻塞

接收方收到的數(shù)據(jù)范圍必須在接收窗口范圍內(nèi)肯适,如果收到超過接收窗口范圍的數(shù)據(jù)变秦,就會(huì)丟棄該數(shù)據(jù),比如下圖接收窗口的范圍是 32 ~ 51 字節(jié)疹娶,如果收到第 52 字節(jié)以上數(shù)據(jù)都會(huì)被丟棄

7c9b2dcd4a71327d4f723264be9905ae_89eb77d2fdf44fbcb0b5ceb35724edfe.png

接收窗口什么時(shí)候才能滑動(dòng)伴栓?當(dāng)接收窗口收到有序數(shù)據(jù)時(shí)伦连,接收窗口才能往前滑動(dòng)雨饺,然后那些已經(jīng)接收并且被確認(rèn)的有序數(shù)據(jù)就可以被應(yīng)用層讀取。

但是惑淳,當(dāng)接收窗口收到的數(shù)據(jù)不是有序的额港,比如收到第 33~40 字節(jié)的數(shù)據(jù),由于第 32 字節(jié)數(shù)據(jù)沒有收到歧焦, 接收窗口無法向前滑動(dòng)移斩,那么即使先收到第 33~40 字節(jié)的數(shù)據(jù)肚医,這些數(shù)據(jù)也無法被應(yīng)用層讀取的。只有當(dāng)發(fā)送方重傳了第 32 字節(jié)數(shù)據(jù)并且被接收方收到后向瓷,接收窗口才會(huì)往前滑動(dòng)肠套,然后應(yīng)用層才能從內(nèi)核讀取第 32~40 字節(jié)的數(shù)據(jù)

至此發(fā)送窗口和接收窗口的隊(duì)頭阻塞問題都說完了,這兩個(gè)問題的原因都是因?yàn)?TCP 必須按序處理數(shù)據(jù)猖任,也就是 TCP 層為了保證數(shù)據(jù)的有序性你稚,只有在處理完有序的數(shù)據(jù)后,滑動(dòng)窗口才能往前滑動(dòng)朱躺,否則就停留刁赖。

停留發(fā)送窗口會(huì)使得發(fā)送方無法繼續(xù)發(fā)送數(shù)據(jù)。
停留接收窗口會(huì)使得應(yīng)用層無法讀取新的數(shù)據(jù)长搀。
其實(shí)也不能怪 TCP 協(xié)議宇弛,它本來設(shè)計(jì)目的就是為了保證數(shù)據(jù)的有序性

1.2.3 HTTP/2 的隊(duì)頭阻塞

HTTP/2 多路復(fù)用解決了上述的隊(duì)頭阻塞問題。在HTTP/2中, 每個(gè)請(qǐng)求都被拆分為多個(gè)Frame通過一條TCP連接同時(shí)被傳輸, 這樣即使一個(gè)請(qǐng)求被阻塞, 也不會(huì)影響其他的請(qǐng)求.
但是, HTTP/2雖然可以解決請(qǐng)求這一粒度下的阻塞, 但HTTP/2的基礎(chǔ)TCP協(xié)議本身卻也存在隊(duì)頭阻塞的問題. HTTP/2的每個(gè)請(qǐng)求都會(huì)被拆分成多個(gè)Frame, 不同請(qǐng)求的Frame組合成Stream, StreamTCP上的邏輯傳輸單元, 這樣HTTP/2就達(dá)到了一條連接同時(shí)發(fā)送多個(gè)請(qǐng)求的目標(biāo), 其中Stram1已經(jīng)正確送達(dá), Stram2中的第三個(gè)Frame丟失, TCP處理數(shù)據(jù)是有嚴(yán)格的前后順序, 先發(fā)送的Frame要先被處理, 這樣就會(huì)要求發(fā)送方重新發(fā)送第三個(gè)Frame, Steam3和Steam4雖然已到達(dá)但卻不能被處理, 那么這時(shí)整條鏈路都會(huì)被阻塞

HTTP/2 通過抽象出 Stream 的概念源请,實(shí)現(xiàn)了 HTTP 并發(fā)傳輸枪芒,一個(gè) Stream 就代表 HTTP/1.1 里的請(qǐng)求和響應(yīng)

e28f6d940a8f876640b7f8863175dee2_5892902959194a5d86d19e5a77c7ac3e.png

HTTP/2 連接上,不同 Stream是可以亂序發(fā)送的(因此可以并發(fā)不同的 Stream )谁尸,因?yàn)槊總€(gè)幀的頭部會(huì)攜帶 Stream ID 信息病苗,所以接收端可以通過 Stream ID 有序組裝成 HTTP 消息,而同一 Stream 內(nèi)部的幀必須是嚴(yán)格有序的症汹。

但是 HTTP/2 多個(gè) Stream 請(qǐng)求都是在一條 TCP 連接上傳輸硫朦,這意味著多個(gè) Stream 共用同一個(gè) TCP 滑動(dòng)窗口,那么當(dāng)發(fā)生數(shù)據(jù)丟失背镇,滑動(dòng)窗口是無法往前移動(dòng)的咬展,此時(shí)就會(huì)阻塞住所有的 HTTP 請(qǐng)求,這屬于 TCP 層隊(duì)頭阻塞瞒斩。

53ab7c66472ee0a3fd1a3c9498bc9e63_0ede28ac3777456789aeb7604bcd291f.png

不僅如此破婆,由于HTTP/2必須使用HTTPS, 而HTTPS使用TLS協(xié)議也存在隊(duì)頭阻塞問題. TLS基于Record組織數(shù)據(jù), 將一對(duì)數(shù)據(jù)放在一起加密, 加密完成后又拆分成多個(gè)TCP包傳輸. 一般每個(gè)Record 16K, 包含12個(gè)TCP包, 這樣如果12個(gè)TCP包中有任何一個(gè)包丟失, 那么整個(gè)Record都無法解密

隊(duì)頭阻塞會(huì)導(dǎo)致HTTP/2在更容易丟包的弱網(wǎng)絡(luò)環(huán)境下比HTTP/1.1更慢.

1.2.4 沒有隊(duì)頭阻塞的 QUIC

QUIC解決隊(duì)頭阻塞的問題主要有兩點(diǎn):

  • QUIC的傳輸單位是Packet, 加密單元也是Packet, 整個(gè)加密, 傳輸, 解密都基于Packet, 這就能避免TLS的阻塞問題.
  • QUIC基于UDP, UDP的數(shù)據(jù)包在接收端沒有處理順序, 即使中間丟失一個(gè)包, 也不會(huì)阻塞整條連接. 其他的資源會(huì)被正常處理.

QUIC 也借鑒 HTTP/2 里的 Stream 的概念,在一條 QUIC 連接上可以并發(fā)發(fā)送多個(gè) HTTP 請(qǐng)求 (Stream)胸囱。但是 QUIC 給每一個(gè) Stream 都分配了一個(gè)獨(dú)立的滑動(dòng)窗口祷舀,這樣使得一個(gè)連接上的多個(gè) Stream 之間沒有依賴關(guān)系,都是相互獨(dú)立的烹笔,各自控制的滑動(dòng)窗口裳扯。

假如 Stream2 丟了一個(gè) UDP 包,也只會(huì)影響 Stream2 的處理谤职,不會(huì)影響其他 Stream饰豺,與 HTTP/2 不同,HTTP/2 只要某個(gè)流中的數(shù)據(jù)包丟失了允蜈,其他流也會(huì)因此受影響冤吨。

4c75995eb36cd95371749cb615ce8ca2_01d32d3dc8cc451a894a94d562789ddc.png

1.3 TCP 建立連接的延遲

對(duì)于 HTTP/1HTTP/2 協(xié)議蒿柳,TCPTLS 是分層的,分別屬于內(nèi)核實(shí)現(xiàn)的傳輸層漩蟆、openssl 庫實(shí)現(xiàn)的表示層垒探,因此它們難以合并在一起,需要分批次來握手怠李,先 TCP 握手(1RTT)叛复,再 TLS 握手(2RTT),所以需要 3RTT 的延遲才能傳輸數(shù)據(jù)扔仓,就算 Session 會(huì)話服務(wù)褐奥,也需要至少 2 個(gè) RTT,這在一定程序上增加了數(shù)據(jù)傳輸?shù)难舆t翘簇。

RTT: round-trip time, 僅包括請(qǐng)求訪問來回的時(shí)間

TCP 三次握手和 TLS 握手延遲撬码,如圖:

48c4c9e72432a706052d22a43dd5eba7_24612012bd7d40e396fbf2673014f115.png

HTTP/3 在傳輸數(shù)據(jù)前雖然需要 QUIC 協(xié)議握手,這個(gè)握手過程只需要 1 RTT版保,握手的目的是為確認(rèn)雙方的連接 ID呜笑,連接遷移就是基于連接 ID 實(shí)現(xiàn)的。
但是 HTTP/3QUIC 協(xié)議并不是與 TLS 分層彻犁,因?yàn)?QUIC 也是應(yīng)用層實(shí)現(xiàn)的協(xié)議叫胁,所以可以將 QUICTLS 協(xié)議握手的過程合并在一起,QUIC 內(nèi)部包含了 TLS汞幢,它在自己的幀會(huì)攜帶 TLS 里的 記錄驼鹅,再加上 QUIC 使用的是 TLS1.3,因此僅需 1 個(gè) RTT 就可以 同時(shí) 完成建立連接與密鑰協(xié)商森篷,甚至在第二次連接的時(shí)候输钩,應(yīng)用數(shù)據(jù)包可以和 QUIC 握手信息(連接信息 + TLS 信息)一起發(fā)送,達(dá)到 0-RTT 的效果仲智。

如下圖右邊部分买乃,HTTP/3 當(dāng)會(huì)話恢復(fù)時(shí),有效負(fù)載數(shù)據(jù)與第一個(gè)數(shù)據(jù)包一起發(fā)送钓辆,可以做到 0-RTT(下圖的右下角):

8f8f2b29464531a569f2f4502b62b51b_6aede2d15a124b628db832dfd3494d5d.png

1.4 HTTP/3 連接過程

HTTP/3首次連接只需要1RTT, 后面的鏈接只需要0RTT, 意味著客戶端發(fā)送給服務(wù)端的第一個(gè)包就帶有請(qǐng)求數(shù)據(jù), 其主要連接過程如下:

  • 首次連接剪验,客戶端發(fā)送Inchoate Client Hello, 用于請(qǐng)求連接;
  • 服務(wù)端生成g, p, a, 根據(jù)g, p, a算出A, 然后將g, p, A放到Server Config中在發(fā)送Rejection消息給客戶端.
  • 客戶端接收到g,p,A后, 自己再生成b, 根據(jù)g,p,a算出B, 根據(jù)A,p,b算出初始密鑰K,B和K算好后, 客戶端會(huì)用K加密HTTP數(shù)據(jù), 連同B一起發(fā)送給服務(wù)端.
  • 服務(wù)端接收到B后, 根據(jù)a,p,B生成與客戶端同樣的密鑰, 再用這密鑰解密收到的HTTP數(shù)據(jù). 為了進(jìn)一步的安全(前向安全性), 服務(wù)端會(huì)更新自己的隨機(jī)數(shù)a和公鑰, 在生成新的密鑰S, 然后把公鑰通過Server Hello發(fā)送給客戶端. 連同Server Hello消息, 還有HTTP返回?cái)?shù)據(jù).
    image.png

這里使用DH密鑰交換算法, DH算法的核心就是服務(wù)端生成a,g,p 3個(gè)隨機(jī)數(shù), a自己持有, g和p要傳輸給客戶端, 而客戶端會(huì)生成b這 1個(gè)隨機(jī)數(shù), 通過DH算法客戶端和服務(wù)端可以算出同樣的密鑰。在這過程中a和b并不參與網(wǎng)絡(luò)傳輸, 安全性大大提升前联。因?yàn)?code>p和g是大數(shù), 所以即使在網(wǎng)絡(luò)傳輸中p, g, A, B都被劫持, 靠現(xiàn)在的計(jì)算力算力也無法破解

1.5 連接遷移影響

基于 TCP 傳輸協(xié)議的 HTTP 協(xié)議功戚,由于是通過 四元組(源IP源端口蛀恩、目的 IP疫铜、目的端口)確定一條 TCP 連接

59e14ac3b9634c30cfc71d96da28fae7_fc618a26f4b54494b5aab9f46faeea7a.png

那么當(dāng)移動(dòng)設(shè)備的網(wǎng)絡(luò)從 4G 切換到 WIFI 時(shí),意味著 IP 地址變化了双谆,那么就必須要斷開連接壳咕,然后重新建立 TCP 連接。

9a86869338507ffb1cfc035465093852_9d006316f34c4c3d8a0d4a4967bfc773.png

而建立連接的過程包含 TCP 三次握手和 TLS 四次握手的時(shí)延顽馋,以及 TCP 慢啟動(dòng)的減速過程谓厘,給用戶的感覺就是網(wǎng)絡(luò)突然卡頓了一下,因此連接的遷移成本是很高的寸谜。
QUIC 協(xié)議沒有用四元組的方式來綁定連接竟稳,而是通過 連接ID來標(biāo)記通信的兩個(gè)端點(diǎn),客戶端和服務(wù)器可以各自選擇一組 ID 來標(biāo)記自己熊痴,因此即使移動(dòng)設(shè)備的網(wǎng)絡(luò)變化后他爸,導(dǎo)致 IP 地址變化了,只要仍保有上下文信息(比如連接 ID果善、TLS 密鑰等)诊笤,就可以 無縫 地復(fù)用原連接,消除重連的成本巾陕,沒有絲毫卡頓感讨跟,達(dá)到了連接遷移的功能。

30494ea299baf232825d6401b48f5c15_a1cd643eb29846d0a95863287d908eb2.png

1.6 擁塞控制影響

擁塞控制的目的是避免過多的數(shù)據(jù)一下子涌入網(wǎng)絡(luò), 導(dǎo)致網(wǎng)絡(luò)超出最大負(fù)荷. QUIC的擁塞控制與TCP類似, 并在此基礎(chǔ)上做了改進(jìn). 先來看看TCP的擁塞控制

  • 慢啟動(dòng): 發(fā)送方向接收方發(fā)送一個(gè)單位的數(shù)據(jù), 收到確認(rèn)后發(fā)送2個(gè)單位, 然后是4個(gè), 8個(gè)依次指數(shù)增長, 這個(gè)過程中不斷試探網(wǎng)絡(luò)的擁塞程度.
  • 避免擁塞: 指數(shù)增長到某個(gè)限制之后, 指數(shù)增長變?yōu)?code>線性增長
  • 快速重傳: 發(fā)送方每一次發(fā)送都會(huì)設(shè)置一個(gè)超時(shí)計(jì)時(shí)器, 超時(shí)后認(rèn)為丟失, 需要重發(fā)
  • 快速恢復(fù): 在上面快速重傳的基礎(chǔ)上, 發(fā)送方重新發(fā)送數(shù)據(jù)時(shí), 也會(huì)啟動(dòng)一個(gè)超時(shí)定時(shí)器, 如果收到確認(rèn)消息則進(jìn)入擁塞避免階段, 如果仍然超時(shí), 則回到慢啟動(dòng)階段.

QUIC重新實(shí)現(xiàn)了TCP協(xié)議中的Cubic算法進(jìn)行擁塞控制, 下面是QUIC改進(jìn)的擁塞控制的特性:

  • 熱插拔
    TCP中如果要修改擁塞控制策略, 需要在系統(tǒng)層面進(jìn)行那個(gè)操作, QUIC修改擁塞控制策略只需要在應(yīng)用層操作, 并且QUIC會(huì)根據(jù)不同的網(wǎng)絡(luò)環(huán)境, 用戶來動(dòng)態(tài)選擇擁塞控制算法.
  • 前向糾錯(cuò) FEC
    QUIC使用前向糾錯(cuò)(FEC, Forword Error Correction)技術(shù)增加協(xié)議的容錯(cuò)性. 一段數(shù)據(jù)被切分為10個(gè)包后, 一次對(duì)每個(gè)包進(jìn)行異或運(yùn)算, 運(yùn)算結(jié)果會(huì)作為FEC包與數(shù)據(jù)包一起被傳輸, 如果傳輸過程中有一個(gè)數(shù)據(jù)包丟失, 那么就可以根據(jù)剩余9個(gè)包以及FEC包推算出丟失的那個(gè)包的數(shù)據(jù), 這樣就大大增加了協(xié)議的容錯(cuò)性.
    這是符合現(xiàn)階段網(wǎng)絡(luò)傳輸技術(shù)的一種方案, 現(xiàn)階段帶寬已經(jīng)不是網(wǎng)絡(luò)傳輸?shù)钠款i, 往返時(shí)間才是, 所以新的網(wǎng)絡(luò)傳輸協(xié)議可以適當(dāng)增加數(shù)據(jù)冗余, 減少重傳操作.
  • 單調(diào)遞增的Packer Number
    TCP為了保證可靠性, 使用Sequence NumberACK來確認(rèn)消息是否有序到達(dá), 但這樣的設(shè)計(jì)存在缺陷.
    超時(shí)發(fā)生后客戶端發(fā)起重傳, 后來接受到了ACK確認(rèn)消息, 但因?yàn)樵颊?qǐng)求和重傳請(qǐng)求接受到的ACK消息一樣, 所以客戶端就不知道這個(gè)ACK對(duì)應(yīng)的是原始請(qǐng)求還是重傳請(qǐng)求. 這就會(huì)造成歧義.
    RTT: Round Trip Time, 往返事件
    RTO: Retransmission Timeout, 超時(shí)重傳時(shí)間
    如果客戶端認(rèn)為是重傳的ACK, 但實(shí)際上是右圖的情形, 會(huì)導(dǎo)致RTT偏小, 反之會(huì)導(dǎo)致RTT偏大.
    image.png

QUIC 解決了上面的的歧義問題, 與Sequence Number不同, Packet Number嚴(yán)格單調(diào)遞增, 如果Packet N丟失了, 那么重傳時(shí)Packet的標(biāo)識(shí)就不會(huì)是N, 而是比N大的數(shù)字, 比如N+M, 這樣發(fā)送方接收到確認(rèn)消息時(shí), 就能方便的知道ACK對(duì)應(yīng)的原始請(qǐng)求還是重傳請(qǐng)求.

  • ACK Delay
    TCP計(jì)算RTT時(shí)沒有考慮接收方接受到數(shù)據(jù)發(fā)發(fā)送方確認(rèn)消息之間的延遲, 如下圖所示, 這段延遲即ACK Delay鄙煤。QUIC考慮了這段延遲, 使得RTT的計(jì)算更加準(zhǔn)確.

    image.png

  • 更多的ACK塊
    一般來說, 接收方收到發(fā)送方的消息后都應(yīng)該發(fā)送一個(gè)ACK恢復(fù), 表示收到了數(shù)據(jù). 但每收到一個(gè)數(shù)據(jù)就返回一個(gè)ACK恢復(fù)實(shí)在太麻煩, 所以一般不會(huì)立即回復(fù), 而是接受到多個(gè)數(shù)據(jù)后再回復(fù), TCP SACK最多提供3個(gè)ACK block. 但在有些場景下, 比如下載, 只需要服務(wù)器返回?cái)?shù)據(jù)就好, 但按照TCP的設(shè)計(jì), 每收到三個(gè)數(shù)據(jù)包就要返回一個(gè)ACK, 而QUIC最多可以捎帶256個(gè)ACK block, 在丟包率比較嚴(yán)重的網(wǎng)絡(luò)下, 更多的ACK可以減少重傳量, 提升網(wǎng)絡(luò)效率

1.7 流量控制影響

TCP會(huì)對(duì)每個(gè)TCP連接進(jìn)行流量控制, 流量控制的意思是讓發(fā)送方不要發(fā)送太快, 要讓接收方來得及接受, 不然會(huì)導(dǎo)致數(shù)據(jù)溢出而丟失, TCP的流量控制主要通過滑動(dòng)窗口來實(shí)現(xiàn)的. 可以看到, 擁塞控制主要是控制發(fā)送方的發(fā)送策略, 但沒有考慮接收方的接收能力, 流量控制則是對(duì)接收方接收能力的一種補(bǔ)充

QUIC只需要建立一條連接, 在這條連接上同時(shí)傳輸多條Stream, 好比有一條道路, 兩邊都分別有一個(gè)倉庫, 道路中有很多車輛運(yùn)送物資. QUIC的流量控制有兩個(gè)級(jí)別: 連接級(jí)別(Connection Level)和Stream 級(jí)別(Stream Level).

對(duì)于單條的Stream的流量控制: Stream還沒傳輸數(shù)據(jù)時(shí), 接收窗口(flow control recevice window)就是最大接收窗口, 隨著接收方接收到數(shù)據(jù)后, 接收窗口不斷縮小. 在接收到的數(shù)據(jù)中, 有的數(shù)據(jù)已被處理, 而有的數(shù)據(jù)還沒來得及處理. 如下圖, 藍(lán)色塊表示已處理數(shù)據(jù), 黃色塊表示違背處理數(shù)據(jù), 這部分?jǐn)?shù)據(jù)的到來, 使得Stream的接收窗口縮小.

image.png

隨著數(shù)據(jù)不斷被處理, 接收方就有能力處理更多數(shù)據(jù). 當(dāng)滿足 (flow control receivce offset - consumed bytes) < (max receive window/2) 時(shí), 接收方會(huì)發(fā)送WINDOW_UPDATE frame 告訴發(fā)送方你可以再多發(fā)送數(shù)據(jù), 這時(shí)候flow control receive offset就會(huì)偏移, 接收窗口增大, 發(fā)送方可以發(fā)送更多數(shù)據(jù)到接收方.

image.png

Stream級(jí)別對(duì)防止接收端接收過多數(shù)據(jù)作用有限, 更需要借助Connection級(jí)別的流量控制. 理解了Stream流量那么也很好理解Connection的流控.
Stream中,接收窗口=最大接受窗口 - 已接收數(shù)據(jù)
而對(duì)于Connection來說:接收窗口 = Stream1 接收窗口 + Stream2 接收窗口 + ... + StreamN 接收窗口

1.8 升級(jí) TCP 的工作很困難

TCP 協(xié)議是誕生在 1973 年晾匠,至今 TCP 協(xié)議依然還在實(shí)現(xiàn)更多的新特性。
但是 TCP 協(xié)議是在內(nèi)核中實(shí)現(xiàn)的梯刚,應(yīng)用程序只能使用不能修改凉馆,如果要想升級(jí) TCP 協(xié)議,那么只能升級(jí)內(nèi)核亡资。
而升級(jí)內(nèi)核這個(gè)工作是很麻煩的事情句喜,麻煩的事情不是說升級(jí)內(nèi)核這個(gè)操作很麻煩,而是由于內(nèi)核升級(jí)涉及到底層軟件和運(yùn)行庫的更新沟于,我們的服務(wù)程序就需要回歸測試是否兼容新的內(nèi)核版本咳胃,所以服務(wù)器的內(nèi)核升級(jí)也比較保守和緩慢。
很多 TCP 協(xié)議的新特性旷太,都是需要客戶端和服務(wù)端同時(shí)支持才能生效的展懈,比如 TCP Fast Open 這個(gè)特性,雖然在2013 年就被提出了供璧,但是 Windows 很多系統(tǒng)版本依然不支持它存崖,這是因?yàn)?PC 端的系統(tǒng)升級(jí)滯后很嚴(yán)重,Windows Xp 現(xiàn)在還有大量用戶在使用睡毒,盡管它已經(jīng)存在快 20 年来惧。

所以,即使 TCP 有比較好的特性更新演顾,也很難快速推廣供搀,用戶往往要幾年或者十年才能體驗(yàn)到隅居。

相反,QUIC 是處于應(yīng)用層的葛虐,所以如果升級(jí) QUIC 協(xié)議的話胎源,其實(shí)就是像升級(jí)軟件一樣輕松。而且屿脐,QUIC 可以針對(duì)不同的應(yīng)用設(shè)置不同的擁塞控制算法涕蚤,這樣靈活性就很高了,這是 TCP 做不到的的诵,因?yàn)?TCP 更改擁塞控制算法是對(duì)系統(tǒng)中所有應(yīng)用都生效万栅,無法根據(jù)不同應(yīng)用設(shè)定不同的擁塞控制策略

1.9 總結(jié)

HTTP/3 拋棄 TCP 后,基于 UDP 實(shí)現(xiàn)的可靠傳輸 QUIC 協(xié)議西疤,帶來這四點(diǎn)好處:

  • 降低連接耗時(shí):在客戶端有緩存的情況下實(shí)現(xiàn)0-RTT建立連接
  • 更靈活的擁塞控制:在用戶態(tài)可以為每個(gè)請(qǐng)求配置不同的擁塞控制策略
  • 無隊(duì)頭阻塞的多路復(fù)用:每個(gè)請(qǐng)求流獨(dú)立擁有滑動(dòng)窗口烦粒,互不影響
  • 連接遷移:網(wǎng)絡(luò)切換不會(huì)中斷數(shù)據(jù)傳輸

不過, HTTP/3 也面臨了一些挑戰(zhàn)瘪阁,QUIC 基于 UDP 協(xié)議在用戶空間實(shí)現(xiàn)的可靠傳輸協(xié)議撒遣,如果一些網(wǎng)絡(luò)設(shè)備無法識(shí)別出 QUIC 協(xié)議,那么在這些網(wǎng)絡(luò)設(shè)備的眼里它就是一個(gè) UDP 協(xié)議管跺。

而幾乎所有的電信運(yùn)營商都會(huì) 歧視 UDP 數(shù)據(jù)包义黎,原因也很容易理解,畢竟歷史上幾次臭名昭著的 DDoS(分布式拒絕服務(wù)攻擊) 攻擊都是基于 UDP 的豁跑。國內(nèi)運(yùn)營商即使沒有封禁 UDP廉涕,也是對(duì) UDP 進(jìn)行嚴(yán)格限流的。

自 2013 年 QUIC 被正式公開以來艇拍,到 2023 年已經(jīng)發(fā)展了差不多 10 年狐蜕,目前網(wǎng)上已經(jīng)有了不少熱門開源的項(xiàng)目,除去帶頭大哥 Google 在完成了對(duì)自身搜索引擎的支持卸夕,還同時(shí)拉上了 Gmail 层释、YouTube 等站點(diǎn)。但對(duì)于國內(nèi)的絕大部分站點(diǎn)來說快集,大部分還是 HTTP/2 協(xié)議贡羔,HTTP/3 之路,似乎還停留在東土大唐

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末个初,一起剝皮案震驚了整個(gè)濱河市乖寒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌院溺,老刑警劉巖楣嘁,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡逐虚,警方通過查閱死者的電腦和手機(jī)聋溜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來痊班,“玉大人勤婚,你說我怎么就攤上這事摹量〉臃ィ” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵缨称,是天一觀的道長凝果。 經(jīng)常有香客問我,道長睦尽,這世上最難降的妖魔是什么器净? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮当凡,結(jié)果婚禮上山害,老公的妹妹穿的比我還像新娘。我一直安慰自己沿量,他們只是感情好浪慌,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朴则,像睡著了一般权纤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乌妒,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天汹想,我揣著相機(jī)與錄音,去河邊找鬼撤蚊。 笑死古掏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的侦啸。 我是一名探鬼主播槽唾,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼匹中!你這毒婦竟也來了夏漱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤顶捷,失蹤者是張志新(化名)和其女友劉穎挂绰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡葵蒂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年交播,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片践付。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秦士,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出永高,到底是詐尸還是另有隱情隧土,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布命爬,位于F島的核電站曹傀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏饲宛。R本人自食惡果不足惜皆愉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艇抠。 院中可真熱鬧幕庐,春花似錦、人聲如沸家淤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媒鼓。三九已至届吁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绿鸣,已是汗流浹背疚沐。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潮模,地道東北人亮蛔。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像擎厢,于是被迫代替她去往敵國和親究流。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容