1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        說一下 HTTP/3 新特性,為什么選擇使用 UDP 協(xié)議?

        共 6053字,需瀏覽 13分鐘

         ·

        2021-09-07 13:56


        點擊上方 三分鐘學(xué)前端,關(guān)注公眾號

        回復(fù)交流,加入前端編程面試算法每日一題群


        面試官也在看的前端面試資料

        引言

        本文主要分為以下幾個方面循序漸進走進 HTTP/3:

        • HTTP/2 和 TCP 的致命缺陷
        • QUIC 協(xié)議為什么選擇 UDP
        • QUIC 和 HTTP/3 新特性
        • QUIC 和 HTTP/3 前景發(fā)展展望

        HTTP/2 和 TCP 的缺陷

        HTTP/2 使用二進制傳輸、Header 壓縮(HPACK)、多路復(fù)用等,相較于 HTTP/1.1 大幅提高了數(shù)據(jù)傳輸效率,但它仍然存在著以下幾個致命問題(主要由底層支撐的 TCP 協(xié)議造成):

        • 建立連接時間長
        • 隊頭阻塞問題相較于 HTTP/1.1 更嚴(yán)重

        1. 建立連接時間長

        RTT 往返時間

        如何定義建立連接時間喃?這里引入一個概念:RTT(Round-Trip Time),往返時間,表示從發(fā)送端發(fā)送數(shù)據(jù)開始,到發(fā)送端收到來自接收端的確認(接收端收到數(shù)據(jù)后便立即發(fā)送確認,不包含數(shù)據(jù)傳輸時間)總共經(jīng)歷的時間,即通信一來一回的時間

        TCP 建立連接時間

        TCP 通過三次揮手建立了 TCP 虛擬通道,它總共需要花費:

        • 一去 (SYN):客戶端向服務(wù)端發(fā)送連接請求報文段。該報文段中包含自身的數(shù)據(jù)通訊初始序號。請求發(fā)送后,客戶端便進入 SYN-SENT 狀態(tài)
        • 二回 (SYN+ACK):服務(wù)端收到連接請求報文段后,如果同意連接,則會發(fā)送一個應(yīng)答,該應(yīng)答中也會包含自身的數(shù)據(jù)通訊初始序號,發(fā)送完成后便進入 SYN-RECEIVED 狀態(tài)
        • 三去 (ACK):當(dāng)客戶端收到連接同意的應(yīng)答后,還要向服務(wù)端發(fā)送一個確認報文。客戶端發(fā)完這個報文段后便進入 ESTABLISHED 狀態(tài),服務(wù)端收到這個應(yīng)答后也進入 ESTABLISHED 狀態(tài),此時連接建立成功

        相當(dāng)于一個半來回,故 TCP 建立連接時間 = 1.5 RTT

        HTTP 交易時間

        客戶端在請求數(shù)據(jù)的時候,首先花費 1.5 RTT 建立 TCP 連接,然后 TCP 才開始傳輸 HTTP 請求,瀏覽器收到服務(wù)器的響應(yīng),又要等待的時間為:

        • 一去(HTTP Request)
        • 二回 (HTTP Responses)

        故 HTTP 交易時間 = 1 RTT

        由于 TCP 在第三次握手的時候,不需要等待服務(wù)器端的響應(yīng),所以節(jié)省 0.5 RTT,那么基于 TCP 傳輸?shù)?HTTP 通信,一共花費的時間總和:

        HTTP 通信時間總和 = TCP 建立連接時間 + HTTP 交易時間 = 1 RTT + 1 RTT = 2 RTT

        HTTPS 通信時間

        HTTP/2 延續(xù)了 HTTP/1 的“明文”特點,可以像以前一樣使用明文傳輸數(shù)據(jù),不強制使用加密通信,但 HTTPS 已經(jīng)是大勢所趨,各大主流瀏覽器都公開宣布只支持加密的 HTTP/2,所以,真實應(yīng)用中的 HTTP/2 是還是加密的:

        HTTPS 其實是 HTTP+SSL/TLS 的簡稱

        所以,HTTPS 通信時間 = TCP建立連接時間 +  TLS 連接時間 + HTTP交易時間

        TLS 連接時間

        在 TLS 1.2 協(xié)議的握手,需要 2 個 RTT:

        • 一去:客戶端發(fā)送一個隨機數(shù) C,客戶端的 TLS 版本號以及支持的密碼套件列表給服務(wù)器端
        • 二回:服務(wù)端收到客戶端的隨機值,自己也產(chǎn)生一個隨機值 S ,并根據(jù)客戶端需求的協(xié)議和加密方式來使用對應(yīng)的方式,并且發(fā)送自己的證書(如果需要驗證客戶端證書需要說明)
        • 三去:客戶端收到服務(wù)端的證書并驗證是否有效,驗證通過會再生成一個隨機值 pre-master,通過服務(wù)端證書的公鑰去加密這個隨機值并發(fā)送給服務(wù)端。如果服務(wù)端需要驗證客戶端證書的話會附帶證書(雙向認證,比如網(wǎng)上銀行用 U 盾)
        • 四回: 服務(wù)端收到加密過的隨機值并使用私鑰解密獲得第三個隨機值,這時候兩端都擁有了三個隨機值,可以通過這三個隨機值(C/S 加 pre-master 算出主密鑰)按照之前約定的加密方式生成密鑰,接下來的通信就可以通過該會話密鑰來加密解密

        HTTPS 通信時間總和 = TCP 建立連接時間 + TLS 連接時間 + HTTP交易時間 = 1 RTT + 2 RTT + 1 RTT = 4 RTT

        如果服務(wù)器距離客戶端很近,RTT 時間較短 < 10ms,那么 HTTPS 通信時間也不會超過 40 ms,用戶不會感知,但如果距離較遠,相隔上萬公里,一個 RTT 時間通常在200ms以上,那么 HTTPS 通信將花費 800ms 甚至 1s 以上,這就嚴(yán)重影響到用戶體驗了

        注意:在 TLS 1.3 協(xié)議中,首次建立連接只需要一個 RTT,后面恢復(fù)連接不需要 RTT 了

        HTTPS 通信時間總和(基于TLS1.2) = TCP 建立連接時間 + TLS1.2 連接時間 + HTTP交易時間 = 1 RTT + 2 RTT + 1 RTT = 4 RTT

        HTTPS 通信時間總和(基于TLS1.3) = TCP 建立連接時間 + TLS1.3 連接時間 + HTTP交易時間 = 1 RTT + 1 RTT + 1 RTT = 3 RTT

        2. 隊頭阻塞問題相較于 HTTP/1.1 更嚴(yán)重

        因為 HTTP/2 使用了多路復(fù)用,一般來說同一域名下只需要使用一個 TCP 連接。當(dāng)這個連接中出現(xiàn)了丟包的情況,那就會導(dǎo)致 HTTP/2 的表現(xiàn)情況反倒不如 HTTP/1 了。

        因為在出現(xiàn)丟包的情況下,整個 TCP 都要開始等待重傳,也就導(dǎo)致了后面的所有數(shù)據(jù)都被阻塞了。但是對于 HTTP/1 來說,可以開啟多個 TCP 連接,出現(xiàn)這種情況反到只會影響其中一個連接,剩余的 TCP 連接還可以正常傳輸數(shù)據(jù)。

        QUIC 協(xié)議為什么選擇 UDP

        那么可能就會有人考慮到去修改 TCP 協(xié)議,其實這已經(jīng)是一件不可能完成的任務(wù)了。因為 TCP 存在的時間實在太長,已經(jīng)充斥在各種設(shè)備中,并且這個協(xié)議是由操作系統(tǒng)實現(xiàn)的,更新起來不大現(xiàn)實。

        基于這個原因,Google 就更起爐灶搞了一個基于 UDP 協(xié)議的 QUIC 協(xié)議

        谷歌這樣做看似出乎意料的,但我們對比一下 TCP 與 UDP 就會發(fā)現(xiàn),這是很有道理的:

        • 基于 TCP 開發(fā)的設(shè)備和協(xié)議非常多,兼容困難
        • TCP 協(xié)議棧是 Linux 內(nèi)部的重要部分,修改和升級成本很大
        • UDP 本身是無連接的、沒有建鏈和拆鏈成本
        • UDP 的數(shù)據(jù)包無隊頭阻塞問題
        • UDP 改造成本小

        從上面的對比可以知道,谷歌要想從 TCP 上進行改造升級絕非易事,但是 UDP 雖然沒有 TCP 為了保證可靠連接而引發(fā)的問題,但是 UDP 本身不可靠,又不能直接用。

        所以,谷歌決定在 UDP 基礎(chǔ)上改造一個具備 TCP 協(xié)議優(yōu)點的新協(xié)議也就順理成章了,這個新協(xié)議就是 QUIC 協(xié)議(Quick UDP Internet Connection),并且使用在了 HTTP/3 上,當(dāng)然 HTTP/3 之前名為 HTTP-over-QUIC,從這個名字中我們也可以發(fā)現(xiàn),HTTP/3 最大的改造就是使用了 QUIC

        QUIC 和 HTTP/3 新特性

        QUIC 雖然基于 UDP,但是在原本的基礎(chǔ)上新增了很多功能,比如多路復(fù)用、0-RTT、使用 TLS1.3 加密、流量控制、有序交付、重傳等等功能。這里我們就挑選幾個重要的功能學(xué)習(xí)下這個協(xié)議的內(nèi)容。

        1. 多路復(fù)用,解決隊頭阻塞問題

        雖然 HTTP/2 支持了多路復(fù)用,但是 TCP 協(xié)議終究是沒有這個功能的。QUIC 原生就實現(xiàn)了這個功能

        QUIC 協(xié)議是基于 UDP 協(xié)議實現(xiàn)的,同一個 QUIC 連接上可以創(chuàng)建多個 stream(數(shù)據(jù)流) 來發(fā)送多個 HTTP 請求,并且,多個 stream 之間沒有依賴,傳輸?shù)膯蝹€ stream可以保證有序交付且不會影響其他的數(shù)據(jù)流

        例如下圖,stream2 丟了一個 UDP 包,不會影響后面跟著 Stream3 和 Stream4。這樣的技術(shù)就解決了之前 TCP 存在的隊頭阻塞問題。

        并且 QUIC 在移動端的表現(xiàn)也會比 TCP 好。因為 TCP 是基于 IP 和端口去識別連接的,這種方式在多變的移動端網(wǎng)絡(luò)環(huán)境下是很脆弱的。但是 QUIC 是通過 ID 的方式去識別一個連接,不管你網(wǎng)絡(luò)環(huán)境如何變化,只要 ID 不變,就能迅速重連上。

        2. 0RTT

        通過使用類似 TCP 快速打開的技術(shù),緩存當(dāng)前會話的上下文,在下次恢復(fù)會話的時候,只需要將之前的緩存?zhèn)鬟f給服務(wù)端驗證通過就可以進行傳輸了。

        0RTT 建連可以說是 QUIC 相比 HTTP2 最大的性能優(yōu)勢。那什么是 0RTT 建連呢?

        這里面有兩層含義:

        • 傳輸層 0RTT 就能建立連接。
        • 加密層 0RTT 就能建立加密連接。

        上圖左邊是 HTTPS 的一次完全握手的建連過程,需要 2-3 個 RTT才開始傳輸數(shù)據(jù),右邊 QUIC 協(xié)議在第一個包就可以包含有效的應(yīng)用數(shù)據(jù)

        當(dāng)然,QUIC 協(xié)議可以實現(xiàn) 0RTT ,但這也是有條件的,實際上是首次連接 1RTT,非首次連接 0RTT,首次連接過程:

        可以看到,首次連接的時候,在第 4 步時,就已經(jīng)開始發(fā)送實際的業(yè)務(wù)數(shù)據(jù)了,而第 1 - 3 步正好一去一回花費了 1RTT 時間,所以,首次連接的成本是 1RTT

        3. 向前糾錯機制

        QUIC 協(xié)議有一個非常獨特的特性,稱為向前糾錯 (Forward Error Correction,F(xiàn)EC),每個數(shù)據(jù)包除了它本身的內(nèi)容之外,還包括了部分其他數(shù)據(jù)包的數(shù)據(jù),因此少量的丟包可以通過其他包的冗余數(shù)據(jù)直接組裝而無需重傳。

        向前糾錯犧牲了每個數(shù)據(jù)包可以發(fā)送數(shù)據(jù)的上限,但是減少了因為丟包導(dǎo)致的數(shù)據(jù)重傳,因為數(shù)據(jù)重傳將會消耗更多的時間(包括確認數(shù)據(jù)包丟失、請求重傳、等待新數(shù)據(jù)包等步驟的時間消耗)。

        假如說這次我要發(fā)送三個包,那么協(xié)議會算出這三個包的異或值并單獨發(fā)出一個校驗包,也就是總共發(fā)出了四個包。

        當(dāng)出現(xiàn)其中的非校驗包丟包的情況時,可以通過另外三個包計算出丟失的數(shù)據(jù)包的內(nèi)容。

        當(dāng)然這種技術(shù)只能使用在丟失一個包的情況下,如果出現(xiàn)丟失多個包就不能使用糾錯機制了,只能使用重傳的方式了。

        4. 加密認證的報文

        TCP 協(xié)議頭部沒有經(jīng)過任何加密和認證,所以在傳輸過程中很容易被中間網(wǎng)絡(luò)設(shè)備篡改,注入和竊聽。比如修改序列號、滑動窗口。這些行為有可能是出于性能優(yōu)化,也有可能是主動攻擊。

        但是 QUIC 的 packet 可以說是武裝到了牙齒。除了個別報文比如 PUBLIC_RESET 和 CHLO,所有報文頭部都是經(jīng)過認證的,報文 Body 都是經(jīng)過加密的。

        這樣只要對 QUIC 報文任何修改,接收端都能夠及時發(fā)現(xiàn),有效地降低了安全風(fēng)險。

        如上圖所示,紅色部分是 Stream Frame 的報文頭部,有認證。綠色部分是報文內(nèi)容,全部經(jīng)過加密。

        QUIC 和 HTTP/3 前景發(fā)展展望

        QUIC 協(xié)議雖然是基于 UDP 來實現(xiàn)的,但它將 TCP 的重要功能都進行了實現(xiàn)和優(yōu)化,同時在加密傳輸方向的嘗試也推動了TLS1.3的發(fā)展,未來還是可期的

        只是現(xiàn)在 TCP 協(xié)議的勢力過于強大,很多網(wǎng)絡(luò)設(shè)備甚至對于UDP數(shù)據(jù)包做了很多不友好的策略,所以現(xiàn)在暫時還是 TCP 的天下???♀?,不過 QUIC 已經(jīng)展現(xiàn)了強大的生命力,讓我們拭目以待吧!

        參考

        • 圖解|為什么HTTP3.0使用UDP協(xié)議:https://network.51cto.com/art/202009/625999.htm
        • 如何看待 HTTP/3 ?:https://www.zhihu.com/question/302412059/answer/533223530

        來自:https://github.com/Advanced-Frontend/Daily-Interview-Question

        最后

        歡迎關(guān)注「三分鐘學(xué)前端」,回復(fù)「交流」自動加入前端三分鐘進階群,每日一道編程算法面試題(含解答),助力你成為更優(yōu)秀的前端開發(fā)!
        》》面試官也在看的前端面試資料《《
        “在看和轉(zhuǎn)發(fā)”就是最大的支持


        瀏覽 25
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            公主在御花园吃龙棍的背景故事 | 丰满人妻一区二区三区精品高清 | 在线视频观看一区 | 操b网站在线观看 | 大香蕉人妻在线 | 申鹤被到爽高潮痉挛网站 | www.大香蕉日日撸 | 中文字幕免费在线观看 | 99热免费 | 日韩无码日韩有码 |