QUIC協議詳解


筆記 騰訊工程技術直播-QUIC協議詳解

一、QUIC簡介

QUIC介紹

QUIC是Google開發的基於UDP的傳輸協議,用於提升網絡加載速度。
QUIC發展:2012年部署上線,2013年提交IETF,2021年推出標准RFC9000.

QUIC 協議非常復雜,因為它做了太多事情:
為了實現傳輸的可靠性,它基本上實現並且改進了整個 TCP 協議的功能,包括序列號,重傳,擁塞控制,流量控制等。
為了實現傳輸的安全性,它又徹底重構了 TLS 協議,包括證書壓縮,握手消息,0RTT 等。雖然后續可能會采用 TLS1.3 協議,但是事實上是 QUIC 推動了 TLS1.3 的發展。
為了實現傳輸的並發性,它又實現了 HTTP2 的大部分特性,包括多路復用,流量控制等。

Google現網的QUIC數據

  • PC端:搜索和視頻的傳輸延遲降低了8%
  • 移動端:搜索降低了6%,視頻降低了5.3%

還能發現,在弱網環境下,提升更加明顯。

QUIC是如何提升速度的呢?

二、QUIC的數據包格式

QUIC的數據包分為Header和Data部分,其中Header是明文傳輸,包括Flags是標志位,Connection ID是連接ID,可用於連接遷移,QUIC Version是QUIC的版本號,Packet Number是包序號,用於保證可靠傳輸;Data部分是密文傳輸,是一些數據幀,有很多數據幀類型:Stream、ACK、Padding、Blocked等,其中Stream幀傳輸應用數據

Stream

Frame Type: Bit7~Bit0

  1. Bit7:必須設置為1,表示Stream幀
  2. Bit6:如果設置為1,表示發送端在這個stream上已經結束發送數據,流將處於半關閉狀態
  3. Bit5:如果設置為1,表示Stream頭中包含Data Length字段
  4. Bit432:表示offset的長度。000表示0字節,001表示1字節,002表示2字節,以此類推
  5. Bit10:表示Stream ID的長度。00表示1字節,01表示2字節,10表示3字節,11表示4字節

三、QUIC的實現原理

1. 建立連接

建立https連接

先分析一樣https的握手過程,包括TCP握手和TLS(Transport Layer Security)握手

https連接耗時3個RTT

QUIC基於TLS建立連接

右邊展示的是ECDH算法,一個RTT就可以協商好通信秘鑰。

0-RTT建立連接

還可以0-RTT建立連接,原理在於:客戶端緩存服務端配置ServerConfig(\(B = b*G%P\))
ClientHello: \(A = c*G%P\)
ServerHello: \(B = b*G%P\)
通信秘鑰:\(key = B*c = A*b = b*c*G%P\)
客戶端使用\(key\)發送數據,無需建立連接

0RTT 能實現的關鍵是 ServerConfig。就像 TLS session resume 實現的關鍵是 session id 或者 session ticket 一樣。
ServerConfig 到達服務端后,我們根據 ServerConfig ID 查找本地內存,如果找到了,即認為這個數據是可信的,能夠完成 0RTT 握手。

但是會有兩個問題:

  • 進程間 ID 數據無法共享。
  • 多台服務器間的 ID 數據無法共享。
    明確了問題,那工程層面就需要實現多進程共享及分布式多集群的 ID 共享。

SeverConfig Cache 集群:Stgw 在生成 ServerConfig ID 和內容時,會存儲到全局的 Cache 集群。用戶握手請求落到任意一台 STGW 機器,從全局 Cache 集群都能找到相應的內容,實現 0RTT 握手。

前向安全

QUIC能保證前向安全,什么是前向安全呢?
問題:假設攻擊者記錄所有的通信數據和公開參數,一旦服務器的私鑰\(b\)泄露,則計算計算出通信秘鑰,這樣就可以破解之前的通信數據了
前向安全就是指用來產生會話秘鑰的長期秘鑰泄露出去,不會泄露以前的通訊內容

總結起來就是,通過ServerConfig實現0-RTT握手,通過會話秘鑰保證數據的前向安全

2. 可靠傳輸

QUIC是基於UDP的協議,而UDP是不可靠傳輸,QUIC如何實現可靠傳輸呢?
可靠傳輸必須滿足兩個條件

  • 數據完整性:發送端發出的數據包,接收端都能收到
  • 數據有序性:接收端能按序組裝數據包,解碼得到原始數據

可靠傳輸:數據完整性

實現方案:基於包號PKN和確認應答SACK的丟包重傳機制

PKN是單調遞增的,即使是重傳,PKN也和之前的不一樣。那么接收端怎么保證數據的有序性呢?
通過添加數據包在原始數據中的偏移量offset,接收端根據offset字段對異步到達的數據包進行排序

3. 流量控制

就是說發送端發出的包,接收端要有足夠的緩沖空間來接收。
和TCP一樣,QUIC也是利用滑動窗口機制實現流量控制,也就是連續ARQ協議

如果發送端收到了接收端的ACK幀,窗口就會向右移動,可用窗口就會變大,然后發送新的數據包。

雖然都是采用滑動窗口機制,和TCP不同的是,QUIC的滑動窗口分為Connect和Stream兩種級別。

  • Connnect流量控制:規定了所有數據流的總窗口大小
  • Stream流量控制:規定了每個流的窗口大小

因為QUIC中每個連接上可以發送多個請求,每個請求對應一條流,每個流有自己的滑動窗口,整個連接也有一個滑動窗口,其大小是所有流的可用窗口之和。

4. 擁塞控制

目的:通過擁塞窗口限制發送方的數據量,避免整個網絡擁塞。

它們的目的是不同的,流量控制是為了接防止發送太快,接收方接受不過來,擁塞控制控制是為了防止發送太快,整個網絡擁塞。
發送窗口的大小等於min(接受窗口,擁塞窗口),即 \(swnd = min(rwnd, cwnd)\)
前面講了接收窗口的大小是接收端告訴發送端的,那擁塞窗口的大小怎么得到的呢?
很顯然,擁塞窗口是為了避免網絡擁塞,應該根據網絡擁塞情況動態調整。那怎么判斷網絡的擁塞程度呢?例如發生超時,或連續收到三次相同的ACK等,分為基於丟包的和基於網絡帶寬的。

擁塞控制:慢啟動

初始化:cwnd=1,也就是一個MDS(Max Datagram Size)數據包大小
對於UDP而言:MDS = 1500(MTU)- 20(IP頭部) - 8(UDP頭部) = 1472字節,MTU是指網卡允許的最大包長度。

通過查看QUIC的源碼,發現初始閾值是2000倍的MDS。每收到2倍的ACK,擁塞窗口就增加到2倍。

擁塞控制:擁塞避免

每收到1個ACK,擁塞窗口就增加1。線性增長,一直增長,直達發生丟包。

擁塞控制:擁塞發生

超時重傳,是有一個定時器,在指定時間內沒有收到ACK,就會觸發超時重傳,並進入慢啟動階段;

快速重傳,是指發送端連續收到3個相同的ACK,就會觸發快速重傳,並進入快速恢復階段。

圖中有點小錯誤,cwnd是ssthresh+3,如果是收到n個相同的ACK,則是ssthreash+n。

5. 多路復用

前面有提到QUIC的一大優勢就是解決了隊頭阻塞的問題,什么叫隊頭阻塞,先回顧一個HTTP2協議。

HTTP2

HTTP2首次提出了多路復用,多路復用是指單個HTTP連接上可以同時發送多個HTTP請求,解決了HTTP1.1中單個連接只能發送一個請求的性能瓶頸。
之所以能多路復用,是因為HTTP2和HTTP1.1的幀格式是不同的,其中StreamID就是流的ID,每個請求都是自己的流ID。

  • 1個請求對應1條流
  • 通過Stream ID判斷數據幀屬於哪個請求

假設有A和B兩個請求,對應的Stream ID分別為1和2

在同一個TCP連接中,可以存在兩個流。但是對於TCP連接來說,仍然只有1個滑動窗口來發送這些數據包。所以這就會有隊頭阻塞問題。什么是隊頭阻塞呢?

隊頭阻塞

客戶端將56789發送出去,服務端返回了6789的ACK,但是ACK 5丟失了,會導致發送窗口無法向前移動。也就是說隊頭5阻塞了后面數據包的發送。

多路復用:無隊頭阻塞

實現原理:給每個流都分配一個滑動窗口

雖然單條連接上無隊頭阻塞,但是單條流仍然存在隊頭阻塞。這也很容易理解,單條流還是一個滑動窗口。

6. 連接遷移

QUIC還有一個獨特的優勢:連接遷移,其他協議都沒有這個特性。
定義:當客戶端切換網絡時,和服務端的連接並不會斷開(邏輯上),仍然可以正常通信。
實現原理:QUIC的連接是基於64位的Connection ID,網絡切換時並不會改變Connection ID,連接在邏輯上仍然是通的。
TCP是不行的,TCP是基於四元組(客戶端IP,客戶端Port,服務端IP,服務端端口Port),只要有一個變化連接就會斷開,必須要重新建立連接。

四、總結

問題:QUIC是如何提升網絡加載速度的?

  1. 降低連接耗時:在客戶端有緩存的情況下實現0-RTT建立連接
  2. 更靈活的擁塞控制:在用戶態可以為每個請求配置不同的擁塞控制策略
  3. 無隊頭阻塞的多路復用:每個請求流獨立擁有滑動窗口,互不影響
  4. 連接遷移:網絡切換不會中斷數據傳輸

參考鏈接

  1. 「直播回放」騰訊工程師分享:QUIC協議詳解
  2. 科普:QUIC協議原理分析
  3. 讓互聯網更快的協議,QUIC在騰訊的實踐及性能優化
  4. 扒一扒能加速互聯網的QUIC協議


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM