HTTP3勢(shì)頭這么猛,它的優(yōu)勢(shì)在哪里?
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
HTTP 歷史
QUIC 協(xié)議概覽 QUIC(Quick UDP Internet Connections, 快速UDP網(wǎng)絡(luò)連接)是基于UDP的協(xié)議, 利用了UDP的速度和效率, 同時(shí)整合TCP, TLS和HTTP/2的優(yōu)點(diǎn)并加以優(yōu)化. 用一張圖可以清晰的表示他們之間的關(guān)系. QUIC是用來(lái)替代TCP, SSL/TLS的傳輸層協(xié)議, 在傳輸層之上還有應(yīng)用層. 我們熟知的應(yīng)用層協(xié)議有HTTP, FTP, IMAP等, 這些協(xié)議理論上都可以運(yùn)行在QUIC上, 其中運(yùn)行在QUIC之上的協(xié)議被稱為HTTP/3, 這就是HTTP over QUIC即HTTP/3的含義, 因此想要了解HTTP/3, QUIC是繞不過(guò)去的, 下面是幾個(gè)重要的QUIC特性. RTT建立連接RTT: round-trip time, 僅包括請(qǐng)求訪問(wèn)來(lái)回的時(shí)間
HTTP/3首次連接只需要1RTT, 后面的鏈接只需要0RTT, 意味著客戶端發(fā)送給服務(wù)端的第一個(gè)包就帶有請(qǐng)求數(shù)據(jù), 其主要連接過(guò)程如下:
這里使用DH密鑰交換算法, DH算法的核心就是服務(wù)端生成a,g,p3個(gè)隨機(jī)數(shù), a自己持有, g和p要傳輸給客戶端, 而客戶端會(huì)生成b這1個(gè)隨機(jī)數(shù), 通過(guò)DH算法客戶端和服務(wù)端可以算出同樣的密鑰. 在這過(guò)程中a和b并不參與網(wǎng)絡(luò)傳輸, 安全性大大提升. 因?yàn)閜和g是大數(shù), 所以即使在網(wǎng)絡(luò)傳輸中p, g, A, B都被劫持, 靠現(xiàn)在的計(jì)算力算力也無(wú)法破解. 連接遷移TCP連接基于四元組(源IP, 源端口, 目的IP, 目的端口), 切換網(wǎng)絡(luò)時(shí)至少會(huì)有一個(gè)因素發(fā)生變化, 導(dǎo)致連接發(fā)送變化. 當(dāng)連接發(fā)送變化是, 如果還是用原來(lái)的TCP連接, 則會(huì)導(dǎo)致連接失敗, 就得等到原來(lái)的連接超時(shí)后重新建立連接, 所以我們有時(shí)候發(fā)現(xiàn)切換到一個(gè)新的網(wǎng)絡(luò)時(shí), 即使網(wǎng)絡(luò)狀況良好, 但是內(nèi)容還是需要加載很久. 如果實(shí)現(xiàn)的好, 當(dāng)檢測(cè)到網(wǎng)絡(luò)變化時(shí), 立即建立新的TCP連接, 即使這樣, 建立新的連接還是需要幾百毫秒時(shí)間.
QUIC不以四元素作為表示, 而是使用一個(gè)64位的隨機(jī)數(shù), 這個(gè)隨機(jī)數(shù)被稱為Connection ID, 即使IP或者端口發(fā)生變化, 只要Connection ID沒(méi)有變化, 那么連接依然可以維持. 隊(duì)頭阻塞/多路復(fù)用HTTP/1.1和HTTP/2都存在隊(duì)頭阻塞的問(wèn)題(Head Of Line blocking). TCP是個(gè)面向連接的協(xié)議, 即發(fā)送請(qǐng)求后需要收到ACK消息, 以確認(rèn)對(duì)象已接受數(shù)據(jù). 如果每次請(qǐng)求都要在收到上次請(qǐng)求的ACK消息后再請(qǐng)求, 那么效率無(wú)疑很低. 后來(lái)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ì)頭阻塞的問(wèn)題還是存在的.
但是, HTTP/2雖然可以解決請(qǐng)求這一粒度下的阻塞, 但HTTP/2的基礎(chǔ)TCP協(xié)議本身卻也存在隊(duì)頭阻塞的問(wèn)題. HTTP/2的每個(gè)請(qǐng)求都會(huì)被拆分成多個(gè)Frame, 不同請(qǐng)求的Frame組合成Stream, Stream是TCP上的邏輯傳輸單元, 這樣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必須使用HTTPS, 而HTTPS使用TLS協(xié)議也存在隊(duì)頭阻塞問(wèn)題. TLS基于Record組織數(shù)據(jù), 將一對(duì)數(shù)據(jù)放在一起加密, 加密完成后又拆分成多個(gè)TCP包傳輸. 一般每個(gè)Record 16K, 包含12個(gè)TCP包, 這樣如果12個(gè)TCP包中有任何一個(gè)包丟失, 那么整個(gè)Record都無(wú)法解密. 隊(duì)頭阻塞會(huì)導(dǎo)致HTTP/2在更容易丟包的弱網(wǎng)絡(luò)環(huán)境下比HTTP/1.1更慢. QUIC是如何解決隊(duì)頭阻塞的問(wèn)題的? 主要有兩點(diǎn):
擁塞控制擁塞控制的目的是避免過(guò)多的數(shù)據(jù)一下子涌入網(wǎng)絡(luò), 導(dǎo)致網(wǎng)絡(luò)超出最大負(fù)荷. QUIC的擁塞控制與TCP類似, 并在此基礎(chǔ)上做了改進(jìn). 先來(lái)看看TCP的擁塞控制.
QUIC重新實(shí)現(xiàn)了TCP協(xié)議中的Cubic算法進(jìn)行擁塞控制, 下面是QUIC改進(jìn)的擁塞控制的特性: 1. 熱插拔TCP中如果要修改擁塞控制策略, 需要在系統(tǒng)層面今次那個(gè)操作, QUIC修改擁塞控制策略只需要在應(yīng)用層操作, 并且QUIC會(huì)根據(jù)不同的網(wǎng)絡(luò)環(huán)境, 用戶來(lái)動(dòng)態(tài)選擇擁塞控制算法. 2. 前向糾錯(cuò) FECQUIC使用前向糾錯(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ù)包一起被傳輸, 如果傳輸過(guò)程中有一個(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ù)冗余, 減少重傳操作. 3. 單調(diào)遞增的Packer NumberTCP為了保證可靠性, 使用Sequence Number和ACK來(lái)確認(rèn)消息是否有序到達(dá), 但這樣的設(shè)計(jì)存在缺陷.超時(shí)發(fā)生后客戶端發(fā)起重傳, 后來(lái)接受到了ACK確認(rèn)消息, 但因?yàn)樵颊?qǐng)求和重傳請(qǐng)求接受到的ACK消息一樣, 所以客戶端就不知道這個(gè)ACK對(duì)應(yīng)的是原始請(qǐng)求還是重傳請(qǐng)求. 這就會(huì)造成歧義.
如果客戶端認(rèn)為是重傳的ACK, 但實(shí)際上是右圖的情形, 會(huì)導(dǎo)致RTT偏小, 反之會(huì)導(dǎo)致RTT偏大. QUCI解決了上面的的歧義問(wèn)題, 與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)求. 4. ACK DelayTCP計(jì)算RTT時(shí)沒(méi)有考慮接收方接受到數(shù)據(jù)發(fā)發(fā)送方確認(rèn)消息之間的延遲, 如下圖所示, 這段延遲即ACK Delay. QUIC考慮了這段延遲, 使得RTT的計(jì)算更加準(zhǔn)確. 5. 更多的ACK塊一般來(lái)說(shuō), 接收方收到發(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. 但在有些場(chǎng)景下, 比如下載, 只需要服務(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ò)效率. 瀏覽控制TCP 會(huì)對(duì)每個(gè)TCP連接進(jìn)行流量控制, 流量控制的意思是讓發(fā)送方不要發(fā)送太快, 要讓接收方來(lái)得及接受, 不然會(huì)導(dǎo)致數(shù)據(jù)溢出而丟失, TCP的流量控制主要通過(guò)滑動(dòng)窗口來(lái)實(shí)現(xiàn)的. 可以看到, 擁塞控制主要是控制發(fā)送方的發(fā)送策略, 但沒(méi)有考慮接收方的接收能力, 流量控制是對(duì)部分能力的不起. QUIC只需要建立一條連接, 在這條連接上同時(shí)傳輸多條Stream, 好比有一條道路, 量都分別有一個(gè)倉(cāng)庫(kù), 道路中有很多車輛運(yùn)送物資. QUIC的流量控制有兩個(gè)級(jí)別: 連接級(jí)別(Connection Level)和Stream 級(jí)別(Stream Level). 對(duì)于單條的Stream的流量控制: Stream還沒(méi)傳輸數(shù)據(jù)時(shí), 接收窗口(flow control recevice window)就是最大接收窗口, 隨著接收方接收到數(shù)據(jù)后, 接收窗口不斷縮小. 在接收到的數(shù)據(jù)中, 有的數(shù)據(jù)已被處理, 而有的數(shù)據(jù)還沒(méi)來(lái)得及處理. 如下圖, 藍(lán)色塊表示已處理數(shù)據(jù), 黃色塊表示違背處理數(shù)據(jù), 這部分?jǐn)?shù)據(jù)的到來(lái), 使得Stream的接收窗口縮小. 隨著數(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ù)到接收方. Stream級(jí)別對(duì)防止接收端接收過(guò)多數(shù)據(jù)作用有限, 更需要借助Connection級(jí)別的流量控制. 理解了Stream流量那么也很好理解Connection的流控. Stream中,
而對(duì)于Connection來(lái)說(shuō):
鏈接:https://www.cnblogs.com/YYFaGe/p/16599675.html 該文章在 2024/9/19 18:12:16 編輯過(guò) |
相關(guān)文章
正在查詢... |