字節(jié)一面:如何用 UDP 實現(xiàn)可靠傳輸?

我記得之前在群里看到炕柔,有位讀者字節(jié)一面的時候被問到:「如何基于 UDP 協(xié)議實現(xiàn)可靠傳輸酌泰?

很多同學(xué)第一反應(yīng)就會說把 TCP 可靠傳輸?shù)奶匦裕ㄐ蛄刑枴⒋_認(rèn)應(yīng)答匕累、超時重傳陵刹、流量控制、擁塞控制)在應(yīng)用層實現(xiàn)一遍欢嘿。

實現(xiàn)的思路確實這樣沒錯衰琐,但是有沒有想過,既然 TCP 天然支持可靠傳輸际插,為什么還需要基于 UDP 實現(xiàn)可靠傳輸呢碘耳?這不是重復(fù)造輪子嗎?

所以框弛,我們要先弄清楚 TCP 協(xié)議有哪些痛點辛辨?而這些痛點是否可以在基于 UDP 協(xié)議實現(xiàn)的可靠傳輸協(xié)議中得到改進(jìn)?

在之前這篇文章:TCP 就沒什么缺陷嗎瑟枫?斗搞,我已經(jīng)說了 TCP 協(xié)議四個方面的缺陷:

  • 升級 TCP 的工作很困難;
  • TCP 建立連接的延遲慷妙;
  • TCP 存在隊頭阻塞問題僻焚;
  • 網(wǎng)絡(luò)遷移需要重新建立 TCP 連接;

現(xiàn)在市面上已經(jīng)有基于 UDP 協(xié)議實現(xiàn)的可靠傳輸協(xié)議的成熟方案了膝擂,那就是 QUIC 協(xié)議虑啤,已經(jīng)應(yīng)用在了 HTTP/3。

這次架馋,聊聊 QUIC 是如何實現(xiàn)可靠傳輸?shù)哪剑坑质侨绾谓鉀Q上面 TCP 協(xié)議四個方面的缺陷

image.png

QUIC 是如何實現(xiàn)可靠傳輸?shù)模?/h1>

要基于 UDP 實現(xiàn)的可靠傳輸協(xié)議叉寂,那么就要在應(yīng)用層下功夫萍启,也就是要設(shè)計好協(xié)議的頭部字段。

拿 HTTP/3 舉例子屏鳍,在 UDP 報文頭部與 HTTP 消息之間勘纯,共有 3 層頭部:

image.png

整體看的視角是這樣的:

image.png

接下來,分別對每一個 Header 做個介紹钓瞭。

Packet Header

Packet Header 首次建立連接時和日常傳輸數(shù)據(jù)時使用的 Header 是不同的驳遵。如下圖,注意我沒有把 Header 所有字段都畫出來山涡,只是畫出了重要的字段:

image.png

Packet Header

細(xì)分這兩種:

  • Long Packet Header 用于首次建立連接超埋。
  • Short Packet Header 用于日常傳輸數(shù)據(jù)搏讶。

QUIC 也是需要三次握手來建立連接的佳鳖,主要目的是為了確定連接 ID霍殴。

建立連接時,連接 ID 是由服務(wù)器根據(jù)客戶端的 Source Connection ID 字段生成的系吩,這樣后續(xù)傳輸時来庭,雙方只需要固定住 Destination Connection ID(連接 ID ),從而實現(xiàn)連接遷移功能穿挨。所以月弛,你可以看到日常傳輸數(shù)據(jù)的 Short Packet Header 不需要在傳輸 Source Connection ID 字段了。

Short Packet Header 中的 Packet Number 是每個報文獨(dú)一無二的編號科盛,它是嚴(yán)格遞增的帽衙,也就是說就算 Packet N 丟失了,重傳的 Packet N 的 Packet Number 已經(jīng)不是 N贞绵,而是一個比 N 大的值厉萝。

image.png

為什么要這么設(shè)計呢?

我們先來看看 TCP 的問題榨崩,TCP 在重傳報文時的序列號和原始報文的序列號是一樣的谴垫,也正是由于這個特性,引入了 TCP 重傳的歧義問題母蛛。

image.png

TCP 重傳的歧義問題

比如上圖翩剪,當(dāng) TCP 發(fā)生超時重傳后,客戶端發(fā)起重傳彩郊,然后接收到了服務(wù)端確認(rèn) ACK 前弯。由于客戶端原始報文和重傳報文序列號都是一樣的,那么服務(wù)端針對這兩個報文回復(fù)的都是相同的 ACK秫逝。

這樣的話恕出,客戶端就無法判斷出是原始報文的響應(yīng)還是重傳報文的響應(yīng),這樣在計算 RTT(往返時間) 時應(yīng)該選擇從發(fā)送原始報文開始計算筷登,還是重傳原始報文開始計算呢剃根?

  • 如果算成原始報文的響應(yīng),但實際上是重傳報文的響應(yīng)(上圖右)前方,會導(dǎo)致采樣 RTT 變大狈醉;
  • 如果算成重傳報文的響應(yīng),但實際上是原始報文的響應(yīng)(上圖左)惠险,又很容易導(dǎo)致采樣 RTT 過忻绺怠;

RTT 計算不精確的話班巩,那么 RTO (超時時間)也就不精確渣慕,因為 RTO 是基于 RTT 來計算的嘶炭,RTO 計算不準(zhǔn)確可能導(dǎo)致重傳的概率事件增大。

QUIC 報文中的 Pakcet Number 是嚴(yán)格遞增的逊桦, 即使是重傳報文眨猎,它的 Pakcet Number 也是遞增的,這樣就能更加精確計算出報文的 RTT强经。

image.png

如果 ACK 的 Packet Number 是 N+M睡陪,就根據(jù)重傳報文計算采樣 RTT。如果 ACK 的 Pakcet Number 是 N匿情,就根據(jù)原始報文的時間計算采樣 RTT兰迫,沒有歧義性的問題。

另外炬称,還有一個好處汁果,QUIC 使用的 Packet Number 單調(diào)遞增的設(shè)計,可以讓數(shù)據(jù)包不再像TCP 那樣必須有序確認(rèn)玲躯,QUIC 支持亂序確認(rèn)据德,當(dāng)數(shù)據(jù)包Packet N 丟失后,只要有新的已接收數(shù)據(jù)包確認(rèn)府蔗,當(dāng)前窗口就會繼續(xù)向右滑動晋控。

待發(fā)送端超過一定時間沒收到 Packet N 的確認(rèn)報文后,會將需要重傳的數(shù)據(jù)包放到待發(fā)送隊列姓赤,重新編號比如數(shù)據(jù)包 Packet N+M 后重新發(fā)送給接收端赡译,對重傳數(shù)據(jù)包的處理跟發(fā)送新的數(shù)據(jù)包類似,這樣就不會因為丟包重傳將當(dāng)前窗口阻塞在原地不铆,從而解決了隊頭阻塞問題蝌焚。

所以,Packet Number 單調(diào)遞增的兩個好處:

  • 可以更加精確計算 RTT誓斥,沒有 TCP 重傳的歧義性問題只洒;
  • 可以支持亂序確認(rèn),防止因為丟包重傳將當(dāng)前窗口阻塞在原地劳坑,而 TCP 必須是順序確認(rèn)的毕谴,丟包時會導(dǎo)致窗口滑動;

QUIC Frame Header

一個 Packet 報文中可以存放多個 QUIC Frame距芬。

image.png

每一個 Frame 都有明確的類型涝开,針對類型的不同,功能也不同框仔,自然格式也不同舀武。我這里只舉例 Stream 類型的 Frame 格式,Stream 可以認(rèn)為就是一條 HTTP 請求离斩,它長這樣:

image.png
  • Stream ID 作用:多個并發(fā)傳輸?shù)?HTTP 消息银舱,通過不同的 Stream ID 加以區(qū)別瘪匿;
  • Offset 作用:類似于 TCP 協(xié)議中的 Seq 序號,保證數(shù)據(jù)的順序性和可靠性寻馏;
  • Length 作用:指明了 Frame 數(shù)據(jù)的長度棋弥。

在前面介紹 Packet Header 時,說到 Packet Number 是嚴(yán)格遞增操软,即使重傳報文的 Packet Number 也是遞增的嘁锯,既然重傳數(shù)據(jù)包的 Packet N+M 與丟失數(shù)據(jù)包的 Packet N 編號并不一致,我們怎么確定這兩個數(shù)據(jù)包的內(nèi)容一樣呢聂薪?

所以引入 Frame Header 這一層,通過 Stream ID + Offset 字段信息實現(xiàn)數(shù)據(jù)的有序性蝗羊,通過比較兩個數(shù)據(jù)包的 Stream ID 與 Stream Offset 藏澳,如果都是一致,就說明這兩個數(shù)據(jù)包的內(nèi)容一致耀找。

舉個例子翔悠,下圖中,數(shù)據(jù)包 Packet N 丟失了野芒,后面重傳該數(shù)據(jù)包的編號為 Packet N+2蓄愁,丟失的數(shù)據(jù)包和重傳的數(shù)據(jù)包 Stream ID 與 Offset 都一致,說明這兩個數(shù)據(jù)包的內(nèi)容一致狞悲。這些數(shù)據(jù)包傳輸?shù)浇邮斩撕蟠樽ィ邮斩四芨鶕?jù) Stream ID 與 Offset 字段信息將 Stream x 和 Stream x+y 按照順序組織起來,然后交給應(yīng)用程序處理摇锋。

image.png

總的來說丹拯,QUIC 通過單向遞增的 Packet Number,配合 Stream ID 與 Offset 字段信息荸恕,可以支持亂序確認(rèn)而不影響數(shù)據(jù)包的正確組裝乖酬,擺脫了TCP 必須按順序確認(rèn)應(yīng)答 ACK 的限制,解決了 TCP 因某個數(shù)據(jù)包重傳而阻塞后續(xù)所有待發(fā)送數(shù)據(jù)包的問題融求。

QUIC 是如何解決 TCP 隊頭阻塞問題的咬像?

什么是 TCP 隊頭阻塞問題?

TCP 隊頭阻塞的問題要從兩個角度看生宛,一個是發(fā)送窗口的隊頭阻塞县昂,另外一個是接收窗口的隊頭阻塞

先來說說發(fā)送窗口的隊頭阻塞茅糜。

TCP 發(fā)送出去的數(shù)據(jù)七芭,都是需要按序確認(rèn)的,只有在數(shù)據(jù)都被按順序確認(rèn)完后蔑赘,發(fā)送窗口才會往前滑動狸驳。

舉個例子预明,比如下圖的發(fā)送方把發(fā)送窗口內(nèi)的數(shù)據(jù)全部都發(fā)出去了,可用窗口的大小就為 0 了耙箍,表明可用窗口耗盡撰糠,在沒收到 ACK 確認(rèn)之前是無法繼續(xù)發(fā)送數(shù)據(jù)了。

image.png

可用窗口耗盡

接著辩昆,當(dāng)發(fā)送方收到對第 32~36 字節(jié)的 ACK 確認(rèn)應(yīng)答后阅酪,則滑動窗口往右邊移動 5 個字節(jié),因為有 5 個字節(jié)的數(shù)據(jù)被應(yīng)答確認(rèn)汁针,接下來第 52~56 字節(jié)又變成了可用窗口术辐,那么后續(xù)也就可以發(fā)送 52~56 這 5 個字節(jié)的數(shù)據(jù)了。

image.png

32 ~ 36 字節(jié)已確認(rèn)

但是如果某個數(shù)據(jù)報文丟失或者其對應(yīng)的 ACK 報文在網(wǎng)絡(luò)中丟失施无,會導(dǎo)致發(fā)送方無法移動發(fā)送窗口辉词,這時就無法再發(fā)送新的數(shù)據(jù),只能超時重傳這個數(shù)據(jù)報文猾骡,直到收到這個重傳報文的 ACK瑞躺,發(fā)送窗口才會移動,繼續(xù)后面的發(fā)送行為兴想。

舉個例子幢哨,比如下圖,客戶端是發(fā)送方嫂便,服務(wù)器是接收方捞镰。

image.png

客戶端發(fā)送了第 5~9 字節(jié)的數(shù)據(jù),但是第 5 字節(jié)的 ACK 確認(rèn)報文在網(wǎng)絡(luò)中丟失了顽悼,那么即使客戶端收到第 6~9 字節(jié)的 ACK 確認(rèn)報文曼振,發(fā)送窗口也不會往前移動。

此時的第 5 字節(jié)相當(dāng)于“隊頭”蔚龙,因為沒有收到“隊頭”的 ACK 確認(rèn)報文冰评,導(dǎo)致發(fā)送窗口無法往前移動,此時發(fā)送方就無法繼續(xù)發(fā)送后面的數(shù)據(jù)木羹,相當(dāng)于按下了發(fā)送行為的暫停鍵甲雅,這就是發(fā)送窗口的隊頭阻塞問題

再來說說接收窗口的隊頭阻塞坑填。

接收方收到的數(shù)據(jù)范圍必須在接收窗口范圍內(nèi)抛人,如果收到超過接收窗口范圍的數(shù)據(jù),就會丟棄該數(shù)據(jù)脐瑰,比如下圖接收窗口的范圍是 32 ~ 51 字節(jié)妖枚,如果收到第 52 字節(jié)以上數(shù)據(jù)都會被丟棄。

image.png

接收窗口

接收窗口什么時候才能滑動苍在?當(dāng)接收窗口收到有序數(shù)據(jù)時绝页,接收窗口才能往前滑動荠商,然后那些已經(jīng)接收并且被確認(rèn)的「有序」數(shù)據(jù)就可以被應(yīng)用層讀取。

但是续誉,當(dāng)接收窗口收到的數(shù)據(jù)不是有序的莱没,比如收到第 33~40 字節(jié)的數(shù)據(jù),由于第 32 字節(jié)數(shù)據(jù)沒有收到酷鸦, 接收窗口無法向前滑動饰躲,那么即使先收到第 33~40 字節(jié)的數(shù)據(jù),這些數(shù)據(jù)也無法被應(yīng)用層讀取的臼隔。只有當(dāng)發(fā)送方重傳了第 32 字節(jié)數(shù)據(jù)并且被接收方收到后嘹裂,接收窗口才會往前滑動,然后應(yīng)用層才能從內(nèi)核讀取第 32~40 字節(jié)的數(shù)據(jù)躬翁。

好了焦蘑,至此發(fā)送窗口和接收窗口的隊頭阻塞問題都說完了,這兩個問題的原因都是因為 TCP 必須按序處理數(shù)據(jù)盒发,也就是 TCP 層為了保證數(shù)據(jù)的有序性,只有在處理完有序的數(shù)據(jù)后狡逢,滑動窗口才能往前滑動宁舰,否則就停留。

  • 停留「發(fā)送窗口」會使得發(fā)送方無法繼續(xù)發(fā)送數(shù)據(jù)奢浑。
  • 停留「接收窗口」會使得應(yīng)用層無法讀取新的數(shù)據(jù)蛮艰。

其實也不能怪 TCP 協(xié)議,它本來設(shè)計目的就是為了保證數(shù)據(jù)的有序性雀彼。

HTTP/2 的隊頭阻塞

HTTP/2 通過抽象出 Stream 的概念壤蚜,實現(xiàn)了 HTTP 并發(fā)傳輸,一個 Stream 就代表 HTTP/1.1 里的請求和響應(yīng)徊哑。

image.png

HTTP/2

在 HTTP/2 連接上袜刷,不同 Stream 的幀是可以亂序發(fā)送的(因此可以并發(fā)不同的 Stream ),因為每個幀的頭部會攜帶 Stream ID 信息莺丑,所以接收端可以通過 Stream ID 有序組裝成 HTTP 消息著蟹,而同一 Stream 內(nèi)部的幀必須是嚴(yán)格有序的。

但是 HTTP/2 多個 Stream 請求都是在一條 TCP 連接上傳輸梢莽,這意味著多個 Stream 共用同一個 TCP 滑動窗口萧豆,那么當(dāng)發(fā)生數(shù)據(jù)丟失,滑動窗口是無法往前移動的昏名,此時就會阻塞住所有的 HTTP 請求涮雷,這屬于 TCP 層隊頭阻塞

image.png

沒有隊頭阻塞的 QUIC

QUIC 也借鑒 HTTP/2 里的 Stream 的概念轻局,在一條 QUIC 連接上可以并發(fā)發(fā)送多個 HTTP 請求 (Stream)洪鸭。

但是 QUIC 給每一個 Stream 都分配了一個獨(dú)立的滑動窗口样刷,這樣使得一個連接上的多個 Stream 之間沒有依賴關(guān)系,都是相互獨(dú)立的卿嘲,各自控制的滑動窗口颂斜。

假如 Stream2 丟了一個 UDP 包,也只會影響 Stream2 的處理拾枣,不會影響其他 Stream沃疮,與 HTTP/2 不同,HTTP/2 只要某個流中的數(shù)據(jù)包丟失了梅肤,其他流也會因此受影響司蔬。

image.png

QUIC 是如何做流量控制的?

TCP 流量控制是通過讓「接收方」告訴「發(fā)送方」姨蝴,它(接收方)的接收窗口有多大俊啼,從而讓「發(fā)送方」根據(jù)「接收方」的實際接收能力控制發(fā)送的數(shù)據(jù)量。

在前面說到左医,TCP 的接收窗口在收到有序的數(shù)據(jù)后授帕,接收窗口才能往前滑動,否則停止滑動浮梢;TCP 的發(fā)送窗口在收到對已發(fā)送數(shù)據(jù)的順序確認(rèn) ACK后跛十,發(fā)送窗口才能往前滑動,否則停止滑動秕硝。

QUIC 是基于 UDP 傳輸?shù)慕嬗常?UDP 沒有流量控制,因此 QUIC 實現(xiàn)了自己的流量控制機(jī)制远豺。不過奈偏,QUIC 的滑動窗口滑動的條件跟 TCP 有所差別的

QUIC 實現(xiàn)了兩種級別的流量控制躯护,分別為 Stream 和 Connection 兩種級別:

  • Stream 級別的流量控制:每個 Stream 都有獨(dú)立的滑動窗口惊来,所以每個 Stream 都可以做流量控制,防止單個 Stream 消耗連接(Connection)的全部接收緩沖榛做。
  • Connection 流量控制:限制連接中所有 Stream 相加起來的總字節(jié)數(shù)唁盏,防止發(fā)送方超過連接的緩沖容量。

Stream 級別的流量控制

回想一下 TCP检眯,當(dāng)發(fā)送方發(fā)送 seq1厘擂、seq2、seq3 報文锰瘸,由于 seq2 報文丟失了刽严,接收方收到 seq1 后會 ack1,然后接收方收到 seq3 后還是回 ack1(因為沒有收到 seq2),這時發(fā)送窗口無法往前滑動舞萄。

但是眨补,QUIC 就不一樣了,即使中途有報文丟失倒脓,發(fā)送窗口依然可以往前滑動撑螺,具體怎么做到的呢?我們來看看崎弃。

最開始甘晤,接收方的接收窗口初始狀態(tài)如下:

image.png

接著,接收方收到了發(fā)送方發(fā)送過來的數(shù)據(jù)饲做,有的數(shù)據(jù)被上層讀取了线婚,有的數(shù)據(jù)丟包了,此時的接收窗口狀況如下:

image.png

可以看到盆均,接收窗口的左邊界取決于接收到的最大偏移字節(jié)數(shù)塞弊,此時的接收窗口 = 最大窗口數(shù) - 接收到的最大偏移數(shù),這里就跟 TCP 不一樣了泪姨。

image.png

接收窗口觸發(fā)的滑動

當(dāng)圖中的綠色部分?jǐn)?shù)據(jù)超過最大接收窗口的一半后游沿,最大接收窗口向右移動,同時給對端發(fā)送「窗口更新幀」肮砾。當(dāng)發(fā)送方收到接收方的窗口更新幀后奏候,發(fā)送窗口也會往前滑動,即使中途有丟包唇敞,依然也會滑動,這樣就防止像 TCP 那樣在出現(xiàn)丟包的時候咒彤,導(dǎo)致發(fā)送窗口無法移動疆柔,從而避免了無法繼續(xù)發(fā)送數(shù)據(jù)。

在前面我們說過镶柱,每個 Stream 都有各自的滑動窗口旷档,不同 Stream 互相獨(dú)立,隊頭的 Stream A 被阻塞后歇拆,不妨礙 StreamB鞋屈、C的讀取。而對于 TCP 而言故觅,其不知道將不同的 Stream 交給上層哪一個請求厂庇,因此同一個Connection內(nèi),Stream A 被阻塞后输吏,StreamB权旷、C 必須等待。

經(jīng)過了解完 QUIC 的流量控制機(jī)制后贯溅,對于隊頭阻塞問題解決得更加徹底拄氯。

QUIC 協(xié)議中同一個 Stream 內(nèi)躲查,滑動窗口的移動僅取決于接收到的最大字節(jié)偏移(盡管期間可能有部分?jǐn)?shù)據(jù)未被接收),而對于 TCP 而言译柏,窗口滑動必須保證此前的 packet 都有序的接收到了镣煮,其中一個 packet 丟失就會導(dǎo)致窗口等待。

Connection 流量控制

而對于 Connection 級別的流量窗口鄙麦,其接收窗口大小就是各個 Stream 接收窗口大小之和典唇。

image.png

Connection 流量控制

上圖所示的例子,所有 Streams 的最大窗口數(shù)為 120黔衡,其中:

  • Stream 1 的最大接收偏移為 100蚓聘,可用窗口 = 120 - 100 = 20
  • Stream 2 的最大接收偏移為 90,可用窗口 = 120 - 90 = 30
  • Stream 3 的最大接收偏移為 110盟劫,可用窗口 = 120 - 110 = 10

那么整個 Connection 的可用窗口 = 20 + 30 + 10 = 60

可用窗口 = Stream 1 可用窗口 + Stream 2 可用窗口 + Stream 3 可用窗口

QUIC 對擁塞控制改進(jìn)

QUIC 協(xié)議當(dāng)前默認(rèn)使用了 TCP 的 Cubic 擁塞控制算法(我們熟知的慢開始夜牡、擁塞避免、快重傳侣签、快恢復(fù)策略)塘装,同時也支持 CubicBytes、Reno影所、RenoBytes蹦肴、BBR、PCC 等擁塞控制算法猴娩,相當(dāng)于將 TCP 的擁塞控制算法照搬過來了阴幌,QUIC 是如何改進(jìn) TCP 的擁塞控制算法的呢?

QUIC 是處于應(yīng)用層的卷中,應(yīng)用程序?qū)用婢湍軐崿F(xiàn)不同的擁塞控制算法矛双,不需要操作系統(tǒng),不需要內(nèi)核支持蟆豫。這是一個飛躍议忽,因為傳統(tǒng)的 TCP 擁塞控制,必須要端到端的網(wǎng)絡(luò)協(xié)議棧支持十减,才能實現(xiàn)控制效果栈幸。而內(nèi)核和操作系統(tǒng)的部署成本非常高,升級周期很長帮辟,所以 TCP 擁塞控制算法迭代速度是很慢的速址。而 QUIC 可以隨瀏覽器更新,QUIC 的擁塞控制算法就可以有較快的迭代速度织阅。

TCP 更改擁塞控制算法是對系統(tǒng)中所有應(yīng)用都生效壳繁,無法根據(jù)不同應(yīng)用設(shè)定不同的擁塞控制策略。但是因為 QUIC 處于應(yīng)用層,所以就可以針對不同的應(yīng)用設(shè)置不同的擁塞控制算法闹炉,這樣靈活性就很高了蒿赢。

QUIC 更快的連接建立

對于 HTTP/1 和 HTTP/2 協(xié)議,TCP 和 TLS 是分層的渣触,分別屬于內(nèi)核實現(xiàn)的傳輸層羡棵、openssl 庫實現(xiàn)的表示層,因此它們難以合并在一起嗅钻,需要分批次來握手皂冰,先 TCP 握手(1RTT),再 TLS 握手(2RTT)养篓,所以需要 3RTT 的延遲才能傳輸數(shù)據(jù)秃流,就算 Session 會話服用,也需要至少 2 個 RTT柳弄。

HTTP/3 在傳輸數(shù)據(jù)前雖然需要 QUIC 協(xié)議握手舶胀,這個握手過程只需要 1 RTT,握手的目的是為確認(rèn)雙方的「連接 ID」碧注,連接遷移就是基于連接 ID 實現(xiàn)的嚣伐。

但是 HTTP/3 的 QUIC 協(xié)議并不是與 TLS 分層,而是QUIC 內(nèi)部包含了 TLS萍丐,它在自己的幀會攜帶 TLS 里的“記錄”轩端,再加上 QUIC 使用的是 TLS1.3,因此僅需 1 個 RTT 就可以「同時」完成建立連接與密鑰協(xié)商逝变,甚至在第二次連接的時候基茵,應(yīng)用數(shù)據(jù)包可以和 QUIC 握手信息(連接信息 + TLS 信息)一起發(fā)送,達(dá)到 0-RTT 的效果壳影。

如下圖右邊部分耿导,HTTP/3 當(dāng)會話恢復(fù)時态贤,有效負(fù)載數(shù)據(jù)與第一個數(shù)據(jù)包一起發(fā)送醋火,可以做到 0-RTT:

image.png

QUIC 是如何遷移連接的?

基于 TCP 傳輸協(xié)議的 HTTP 協(xié)議芥驳,由于是通過四元組(源 IP柿冲、源端口假抄、目的 IP、目的端口)確定一條 TCP 連接。

image.png

圖片

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

而建立連接的過程包含 TCP 三次握手和 TLS 四次握手的時延河泳,以及 TCP 慢啟動的減速過程伪朽,給用戶的感覺就是網(wǎng)絡(luò)突然卡頓了一下铭乾,因此連接的遷移成本是很高的。

QUIC 協(xié)議沒有用四元組的方式來“綁定”連接炕檩,而是通過連接 ID來標(biāo)記通信的兩個端點捧书,客戶端和服務(wù)器可以各自選擇一組 ID 來標(biāo)記自己,因此即使移動設(shè)備的網(wǎng)絡(luò)變化后爆哑,導(dǎo)致 IP 地址變化了舆吮,只要仍保有上下文信息(比如連接 ID色冀、TLS 密鑰等),就可以“無縫”地復(fù)用原連接屯换,消除重連的成本与学,沒有絲毫卡頓感,達(dá)到了連接遷移的功能晕窑。

原文鏈接:https://mp.weixin.qq.com/s/hX75YxVOMtsnB6Sm_yjm0g

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末杨赤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子植捎,更是在濱河造成了極大的恐慌说敏,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異架诞,居然都是意外死亡谴忧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門委造,熙熙樓的掌柜王于貴愁眉苦臉地迎上來均驶,“玉大人妇穴,你說我怎么就攤上這事∨荏荩” “怎么了瞒滴?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵妓忍,是天一觀的道長。 經(jīng)常有香客問我,道長搁廓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任蝙场,我火速辦了婚禮售滤,結(jié)果婚禮上台诗,老公的妹妹穿的比我還像新娘。我一直安慰自己弊知,他們只是感情好粱快,可當(dāng)我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布事哭。 她就那樣靜靜地躺著鳍咱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澎现。 梳的紋絲不亂的頭發(fā)上每辟,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天渠欺,我揣著相機(jī)與錄音,去河邊找鬼胳岂。 笑死舔稀,一個胖子當(dāng)著我的面吹牛内贮,可吹牛的內(nèi)容都是我干的汞斧。 我是一名探鬼主播什燕,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼屎即,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乘陪?” 一聲冷哼從身側(cè)響起虽另,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤捂刺,失蹤者是張志新(化名)和其女友劉穎族展,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贵涵,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恰画,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年拴还,在試婚紗的時候發(fā)現(xiàn)自己被綠了片林。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡焕妙,死狀恐怖弓摘,靈堂內(nèi)的尸體忽然破棺而出韧献,到底是詐尸還是另有隱情爷抓,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布陈莽,位于F島的核電站虽抄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏私植。R本人自食惡果不足惜车酣,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一湖员、第九天 我趴在偏房一處隱蔽的房頂上張望娘摔。 院中可真熱鬧,春花似錦凳寺、人聲如沸肠缨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽惠窄。三九已至漾橙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間脾歇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工池摧, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留激况,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓竭讳,卻偏偏與公主長得像绢慢,于是被迫代替她去往敵國和親洛波。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,515評論 2 359

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