HTTP3勢頭這么猛,它的優勢在哪里?
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
HTTP 歷史
QUIC 協議概覽 QUIC(Quick UDP Internet Connections, 快速UDP網絡連接)是基于UDP的協議, 利用了UDP的速度和效率, 同時整合TCP, TLS和HTTP/2的優點并加以優化. 用一張圖可以清晰的表示他們之間的關系. QUIC是用來替代TCP, SSL/TLS的傳輸層協議, 在傳輸層之上還有應用層. 我們熟知的應用層協議有HTTP, FTP, IMAP等, 這些協議理論上都可以運行在QUIC上, 其中運行在QUIC之上的協議被稱為HTTP/3, 這就是HTTP over QUIC即HTTP/3的含義, 因此想要了解HTTP/3, QUIC是繞不過去的, 下面是幾個重要的QUIC特性. RTT建立連接RTT: round-trip time, 僅包括請求訪問來回的時間
HTTP/3首次連接只需要1RTT, 后面的鏈接只需要0RTT, 意味著客戶端發送給服務端的第一個包就帶有請求數據, 其主要連接過程如下:
這里使用DH密鑰交換算法, DH算法的核心就是服務端生成a,g,p3個隨機數, a自己持有, g和p要傳輸給客戶端, 而客戶端會生成b這1個隨機數, 通過DH算法客戶端和服務端可以算出同樣的密鑰. 在這過程中a和b并不參與網絡傳輸, 安全性大大提升. 因為p和g是大數, 所以即使在網絡傳輸中p, g, A, B都被劫持, 靠現在的計算力算力也無法破解. 連接遷移TCP連接基于四元組(源IP, 源端口, 目的IP, 目的端口), 切換網絡時至少會有一個因素發生變化, 導致連接發送變化. 當連接發送變化是, 如果還是用原來的TCP連接, 則會導致連接失敗, 就得等到原來的連接超時后重新建立連接, 所以我們有時候發現切換到一個新的網絡時, 即使網絡狀況良好, 但是內容還是需要加載很久. 如果實現的好, 當檢測到網絡變化時, 立即建立新的TCP連接, 即使這樣, 建立新的連接還是需要幾百毫秒時間.
QUIC不以四元素作為表示, 而是使用一個64位的隨機數, 這個隨機數被稱為Connection ID, 即使IP或者端口發生變化, 只要Connection ID沒有變化, 那么連接依然可以維持. 隊頭阻塞/多路復用HTTP/1.1和HTTP/2都存在隊頭阻塞的問題(Head Of Line blocking). TCP是個面向連接的協議, 即發送請求后需要收到ACK消息, 以確認對象已接受數據. 如果每次請求都要在收到上次請求的ACK消息后再請求, 那么效率無疑很低. 后來HTTP/1.1提出了Pipeline技術, 允許一個TCP連接同時發送多個請求. 這樣就提升了傳輸效率. 在這樣的背景下, 隊頭阻塞發生了. 比如, 一個TCP連接同時傳輸10個請求, 其中1,2,3個請求給客戶端接收, 但是第四個請求丟失, 那么后面第5-10個請求都被阻塞. 需要等第四個請求處理完畢后才能被處理. 這樣就浪費了帶寬資源. 因此, HTTP一般又允許每個主機建立6個TCP連接, 這樣可以更加充分的利用帶寬資源, 但每個連接中隊頭阻塞的問題還是存在的.
但是, HTTP/2雖然可以解決請求這一粒度下的阻塞, 但HTTP/2的基礎TCP協議本身卻也存在隊頭阻塞的問題. HTTP/2的每個請求都會被拆分成多個Frame, 不同請求的Frame組合成Stream, Stream是TCP上的邏輯傳輸單元, 這樣HTTP/2就達到了一條連接同時發送多個請求的目標, 其中Stram1已經正確送達, Stram2中的第三個Frame丟失 TCP處理數據是有嚴格的前后順序, 先發送的Frame要先被處理, 這樣就會要求發送方重新發送第三個Frame, Steam3和Steam4雖然已到達但卻不能被處理, 那么這時整條鏈路都會被阻塞. 不僅如此, 由于HTTP/2必須使用HTTPS, 而HTTPS使用TLS協議也存在隊頭阻塞問題. TLS基于Record組織數據, 將一對數據放在一起加密, 加密完成后又拆分成多個TCP包傳輸. 一般每個Record 16K, 包含12個TCP包, 這樣如果12個TCP包中有任何一個包丟失, 那么整個Record都無法解密. 隊頭阻塞會導致HTTP/2在更容易丟包的弱網絡環境下比HTTP/1.1更慢. QUIC是如何解決隊頭阻塞的問題的? 主要有兩點:
擁塞控制擁塞控制的目的是避免過多的數據一下子涌入網絡, 導致網絡超出最大負荷. QUIC的擁塞控制與TCP類似, 并在此基礎上做了改進. 先來看看TCP的擁塞控制.
QUIC重新實現了TCP協議中的Cubic算法進行擁塞控制, 下面是QUIC改進的擁塞控制的特性: 1. 熱插拔TCP中如果要修改擁塞控制策略, 需要在系統層面今次那個操作, QUIC修改擁塞控制策略只需要在應用層操作, 并且QUIC會根據不同的網絡環境, 用戶來動態選擇擁塞控制算法. 2. 前向糾錯 FECQUIC使用前向糾錯(FEC, Forword Error Correction)技術增加協議的容錯性. 一段數據被切分為10個包后, 一次對每個包進行異或運算, 運算結果會作為FEC包與數據包一起被傳輸, 如果傳輸過程中有一個數據包丟失, 那么就可以根據剩余9個包以及FEC包推算出丟失的那個包的數據, 這樣就大大增加了協議的容錯性. 這是符合現階段網絡傳輸技術的一種方案, 現階段帶寬已經不是網絡傳輸的瓶頸, 往返時間才是, 所以新的網絡傳輸協議可以適當增加數據冗余, 減少重傳操作. 3. 單調遞增的Packer NumberTCP為了保證可靠性, 使用Sequence Number和ACK來確認消息是否有序到達, 但這樣的設計存在缺陷.超時發生后客戶端發起重傳, 后來接受到了ACK確認消息, 但因為原始請求和重傳請求接受到的ACK消息一樣, 所以客戶端就不知道這個ACK對應的是原始請求還是重傳請求. 這就會造成歧義.
如果客戶端認為是重傳的ACK, 但實際上是右圖的情形, 會導致RTT偏小, 反之會導致RTT偏大. QUCI解決了上面的的歧義問題, 與Sequence Number不同, Packet Number嚴格單調遞增, 如果Packet N丟失了, 那么重傳時Packet的標識就不會是N, 而是比N大的數字, 比如N+M, 這樣發送方接收到確認消息時, 就能方便的知道ACK對應的原始請求還是重傳請求. 4. ACK DelayTCP計算RTT時沒有考慮接收方接受到數據發發送方確認消息之間的延遲, 如下圖所示, 這段延遲即ACK Delay. QUIC考慮了這段延遲, 使得RTT的計算更加準確. 5. 更多的ACK塊一般來說, 接收方收到發送方的消息后都應該發送一個ACK恢復, 表示收到了數據. 但每收到一個數據就返回一個ACK恢復實在太麻煩, 所以一般不會立即回復, 而是接受到多個數據后再回復, TCP SACK最多提供3個ACK block. 但在有些場景下, 比如下載, 只需要服務器返回數據就好, 但按照TCP的設計, 每收到三個數據包就要返回一個ACK, 而QUIC最多可以捎帶256個ACK block, 在丟包率比較嚴重的網絡下, 更多的ACK可以減少重傳量, 提升網絡效率. 瀏覽控制TCP 會對每個TCP連接進行流量控制, 流量控制的意思是讓發送方不要發送太快, 要讓接收方來得及接受, 不然會導致數據溢出而丟失, TCP的流量控制主要通過滑動窗口來實現的. 可以看到, 擁塞控制主要是控制發送方的發送策略, 但沒有考慮接收方的接收能力, 流量控制是對部分能力的不起. QUIC只需要建立一條連接, 在這條連接上同時傳輸多條Stream, 好比有一條道路, 量都分別有一個倉庫, 道路中有很多車輛運送物資. QUIC的流量控制有兩個級別: 連接級別(Connection Level)和Stream 級別(Stream Level). 對于單條的Stream的流量控制: Stream還沒傳輸數據時, 接收窗口(flow control recevice window)就是最大接收窗口, 隨著接收方接收到數據后, 接收窗口不斷縮小. 在接收到的數據中, 有的數據已被處理, 而有的數據還沒來得及處理. 如下圖, 藍色塊表示已處理數據, 黃色塊表示違背處理數據, 這部分數據的到來, 使得Stream的接收窗口縮小. 隨著數據不斷被處理, 接收方就有能力處理更多數據. 當滿足(flow control receivce offset - consumed bytes) < (max receive window/2)時, 接收方會發送WINDOW_UPDATE frame告訴發送方你可以再多發送數據, 這時候flow control receive offset就會偏移, 接收窗口增大, 發送方可以發送更多數據到接收方. Stream級別對防止接收端接收過多數據作用有限, 更需要借助Connection級別的流量控制. 理解了Stream流量那么也很好理解Connection的流控. Stream中,
而對于Connection來說:
鏈接:https://www.cnblogs.com/YYFaGe/p/16599675.html 該文章在 2024/9/19 18:12:16 編輯過 |
相關文章
正在查詢... |