QUIC是啥?

參考如下,向大佬學習

《基於QUIC傳輸的自適應流媒體技術研究》

技術掃盲:新一代基於UDP的低延時網絡傳輸層協議——QUIC詳解

一泡尿的時間,快速讀懂QUIC協議

---------------------------------------------------------------------------------

        從上個世紀 90 年代互聯網開始興起一直到現在,大部分的互聯網流量傳輸只使用了幾個網絡協議。使用 IPv4 進行路由,使用 TCP 進行連接層面的流量控制,使用 SSL/TLS 協議實現傳輸安全,使用 DNS 進行域名解析,使用 HTTP 進行應用數據的傳輸。三十年來改變不是很大。面對如今龐大的數據傳輸需求,難以支撐。

      QUIC(Quick UDP Internet Connections),是谷歌提出的新的傳輸協議,與之相比的是TCP。衆所周知,TCP建立連接前需要三次握手,如果爲了安全性加入TLS安全協議,握手次數會更多,可見其建立連接的成本高。相比TCP,QUIC可以減少延遲,除了初次建鏈是 1-RTT(三次握手),其餘的建鏈過程通常是 0-RTT(一次握手)

        TCP是在操作系統內核和中間件固件中實現的,所以改變TCP協議幾乎不可能。QUIC是建立在UDP之上實現可靠傳輸,相比TCP,它的流控功能在用戶空間而不在內核空間。QUIC非常類似於在 UDP 上實現的 TCP + TLS + HTTP/2,但與之相比,QUIC存在以下特徵

       1)利用緩存,顯著減少連接建立時間;

       2)改善擁塞控制,擁塞控制從內核空間到用戶空間;

       3)沒有 head of line 阻塞的多路複用;

       4)前向糾錯,減少重傳;

       5)連接平滑遷移,網絡狀態的變更不會影響連接斷線。

                            

        如下圖:QUIC建立於UDP之上,上層使用HTTP/2 API實現與服務器的交互。QUIC 協議已經包含了多路複用和連接管理,HTTP API 只需要完成 HTTP 協議的解析即可。

                                    

        QUIC協議的主要目的,是爲了整合 TCP 協議的可靠性和 UDP 協議的速度和效率。

------------------------------------------------------------

QUIC主要特性介紹    

1、延遲低:QUIC由於建立在 UDP 的基礎上,同時又實現了 0RTT 的安全握手,所以在大部分情況下,只需要 0 個 RTT 就能實現數據發送,在實現前向加密的基礎上,並且 0RTT 的成功率相比 TLS 的 Sesison Ticket要高很多。

2、擁塞控制:默認使用了 TCP 協議的 Cubic 擁塞控制算法,同時也支持 CubicBytes, Reno, RenoBytes, BBR, PCC 等擁塞控制算法。但QUIC有以下改進之處。

        (1)、可插拔:應用程序層面就能實現不同的擁塞控制算法;單個應用程序的不同連接也能支持配置不同的擁塞控制;應用程序不需要停機和升級就能實現擁塞控制的變更。

        (2)、單調遞增的 Packet Number:TCP使用序列號保證可靠性;QUIC使用Packet Number替代序列號,每個 Packet Number 都嚴格遞增,重傳的數據包的number直接遞增,不是原來一樣。

        (3)、不允許 Reneging:QUIC 在協議層面禁止 Reneging,一個 Packet 只要被 Ack,就認爲它一定被正確接收,減少干擾。

        (4)、更多的 Ack 塊:Quic Ack Frame 可以同時提供 256 個 Ack Block,在丟包率比較高的網絡下,更多的 Sack Block 可以提升網絡的恢復速度,減少重傳量。

        (5)、Ack Delay 時間:即接收端收到數據包到發出ACK期間的延遲。QUIC計算RTT如下

                                                   

3、基於 stream 和 connecton 級別的流量控制:提供了stream和connection兩種級別的流量控制。QUIC支持多路複用,多路複用即在一條 Connetion 上會同時存在多條 Stream。既需要對單個 Stream 進行控制,又需要針對所有 Stream 進行總體控制。QUIC的連接級流控,用以限制 QUIC 接收端願意分配給連接的總緩衝區,避免服務器爲某個客戶端分配任意大的緩存。連接級流控與流級流控的過程基本相同,但轉發數據和接收數據的偏移限制是所有流中的總和。

    QUIC的流量控制策略:

        (1)、通過 window_update 幀告訴對端自己可以接收的字節數,這樣發送方就不會發送超過這個數量的數據。

        (2)、通過 BlockFrame 告訴對端由於流量控制被阻塞了,無法發送數據

    QUIC的窗口滑動只取決於接收到的最大偏移字節數。

                                              

                                     

4、沒有隊頭阻塞的多路複用:QUIC 一個連接上的多個 stream 之間沒有依賴。這樣假如 stream2 丟了一個 udp packet,也只會影響 stream2 的處理。不會影響 stream2 之前及之後的 stream 的處理。每個流的幀在到達接收端時能立即分派到該流對應的緩存區,使得沒有丟失的流可以繼續被組裝。QUIC中最基本的傳輸單元是 Packet,傳輸、加密和認證都是基於packet的。與TCP的對比如下兩圖。

                                   

                                

5、加密認證的報文:QUIC除了個別報文所有報文頭部都是經過認證的,報文 Body 都是經過加密的。這樣只要對 QUIC 報文任何修改,接收端都能夠及時發現,有效地降低了安全風險。

6、連接遷移:任何一條 QUIC 連接不再以 IP 及端口四元組標識,而是以一個 64 位的隨機數作爲 ID 來標識,這樣就算 IP 或者端口發生變化時,只要 ID 不變,這條連接依然維持着,上層業務邏輯感知不到變化,不會中斷,也就不需要重連。這個 ID 是客戶端隨機產生的,並且長度有 64 位,衝突概率非常低。

7、數據包流量整形:可以通過調整 Pacing 機制減少數據包丟失。Pacing減少了分組流的波動,從而減少基於擁塞的損耗(即由於溢出而導致的路由器中的分組丟棄)。如圖 2.7,當前 QUIC 是基於帶寬估計來達到動態調整 Pacing 的目的。

                                                  

------------------------------------------------------------

QUIC框架 

                                                          

        如上圖,QUIC 的結構框架主要由認證加密、流量控制、丟失重傳和擁塞控制組成。數據傳輸的實現方式爲一個連接內複用多個流傳輸數據,每個請求對應一個流。QUIC建鏈會使用專用流以實現較小的連接延遲,其他數據通過普通流傳輸。由客戶端主動發起的流 ID 爲奇數,由服務器主動發起的流 ID 爲偶數。認證加密主要在握手的過程中完成;流量控制在接收到 STREAM 幀後作出響應,流關閉後觸發連接級的流量控制;丟失重傳在接收到 ACK 幀後作出響應,ACK包含目前觀測到的最大包序號和未接收到的包的列表;

QUIC 關鍵機制主要分爲四部分,建鏈機制,發包機制,流量控制以及擁塞控制。如下所示。

1、建鏈機制

        加密協議是 QUIC 協議的組成部分,爲 QUIC 數據傳輸過程提供了安全性。由於 QUIC 提出時 TLS1.3還未提出,當前 
QUIC 使用的是臨時的 QUIC 加密協議。QUIC建鏈連接時使用Diffie-Hellman算法結合服務器中週期更新的參數協商祕鑰。首次建立連接時,客戶端發送CHLO包給服務器後,收到服務器的 REJ包,其中包含了服務器的配置參數以及其他信息。客戶端根據REJ 信息生成建立連接需要的相關信息,並將 CHLO 包再次發送給服務器,於此同時發送相關請求的數據。服務器在接受 CHLO 後連接建立,併發送 SHLO 包進行迴應。在建立連接的階段,客戶端與服務器之間同時也完成了祕鑰的交換。之後QUIC數據的交互通過祕鑰進行加密解密。再次傳輸數據時,當前使用的 QUIC 加密協議會在客戶端緩存中保存着服務器的
具體信息。客戶端無需等待服務器的迴應,在發送 CHLO 包後立即發送數據,建立沒有往返時延的加密連接。

                

 2、發包機制

       QUIC開始發送數據前會啓動發包定時器,在收到數據包或者發送定時器超時時觸發發包行爲。QUIC發送非重傳包時,有兩種組包方式,分別是常規組包和快速組包。當發送數據量小於單個QUIC包的有效載荷時使用常規組包;發送數據量大於單個 
QUIC包。有效載荷時,使用快速組包。當發送控制幀或者當前流數據無法填充一個數據包的某些情況(比如存在不能單獨發送的 
ACK 幀)時,QUIC 能進行適當的聚合,利用一個包發送多個幀。

3、流量控制

       QUIC 流量控制是同一個QUIC連接中通信的數據收端通知數據發端當前在每個流上願意接收的數據的多少,以實現對傳輸速率的控制機制。QUIC流量控制中數據收端通過發送流中的絕對字節偏移實現流量控制。QUIC 數據接收端在收到數據後,將數據放入對應的流緩存中並判斷當前能否更新可用窗口。如果可用窗口更新,當可用窗口小於最大接收窗口大小的一半,則數據接收端會更新自己接收窗口大小,併發送Windows update幀給QUIC發送端。QUIC發送端收到Windows update幀後更新發送窗口。

4、擁塞控制

        QUIC擁塞控制借鑑了TCP擁塞控制的思想結合自身的特點重新實現,包括慢啓動,擁塞避免,快速重傳與快速恢復三部分。連接建立初始或由於超時重傳導致的丟包事件時,執行慢啓動;當擁塞窗口大於慢啓動門限時,進入擁塞避免;丟失檢
測出丟包事件時,進入快速恢復;快速恢復結束後進入擁塞避免。QUIC基於UDP上構建了一套控制機制,使得具有可插入的擁塞控制。當前支持的擁塞控制算法有Reno,Cubic 和 BBR。

------------------------------------------------------------

QUIC目前實施的難點

1、IETF上的QUIC 依然還是草稿,並且還存在Google QUIC與IETF QUIC兩類不穩定的協定

2、路由可能封殺UDP 443端口( 這正是QUIC 部署的端口)

3、UDP包過多,由於QS限定,會被服務商誤認爲是攻擊,UDP包被丟棄

4、無論是路由器還是防火牆目前對QUIC都還沒有做好準備

------------------------------------------------------------

實踐:

目前支持 QUIC 協議的 web 服務只有 0.9 版本以後的 Caddy

開源的實現有:

1、Chromium :google官方,編譯比較麻煩,單獨的編譯工具

2、proto-quic :從 chromium 剝離的,不再維護

3、goquic :從 chromium 剝離的,封裝了 libquic 的 go 語言封裝,僅支持到 quic-36,不再維護。

4、quic-go:完全用 go 寫的 QUIC 協議棧,開發很活躍,已在 Caddy 中使用,MIT 許可。

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章