詳解基於UDP的低延時網路傳輸層協議 QUIC

2022-10-11 12:45:13 字數 4354 閱讀 5204

quic 全稱 quick udp internet connection [1],「快速 udp 網際網路連線」,(和英文 quick 諧音,簡稱「快」)是由 google 提出的使用 udp 進行多路併發傳輸的協議。

quic 相比現在廣泛應用的 http2+tcp+tls 協議有如下優勢 [2]:

減少了 tcp 三次握手及 tls 握手時間;

改進的擁塞控制;

避免隊頭阻塞的多路復用;

連線遷移;

前向冗餘糾錯。

從上個世紀 90 年代網際網路開始興起一直到現在,大部分的網際網路流量傳輸只使用了幾個網路協議。使用 ipv4 進行路由,使用 tcp 進行連線層面的流量控制,使用 ssl/tls 協議實現傳輸安全,使用 dns 進行網域名稱解析,使用 http 進行應用資料的傳輸。

而且近三十年來,這幾個協議的發展都非常緩慢。tcp 主要是擁塞控制演算法的改進,ssl/tls 基本上停留在原地,幾個小版本的改動主要是密碼套件的公升級,tls1.3[3] 是乙個飛躍式的變化,但截止到今天,還沒有正式發布。ipv4 雖然有乙個大的進步,實現了 ipv6,dns 也增加了乙個安全的 dnssec,但和 ipv6 一樣,部署進度較慢。

隨著移動網際網路快速發展以及物聯網的逐步興起,網路互動的場景越來越豐富,網路傳輸的內容也越來越龐大,使用者對網路傳輸效率和 web 響應速度的要求也越來越高。

一方面是歷史悠久使用廣泛的古老協議,另外一方面使用者的使用場景對傳輸效能的要求又越來越高。

如下幾個由來已久的問題和矛盾就變得越來越突出:

協議歷史悠久導致中間裝置僵化;

依賴於作業系統的實現導致協議本身僵化;

建立連線的握手延遲大;

隊頭阻塞。

可能是 tcp 協議使用得太久,也非常可靠。所以我們很多中間裝置,包括防火牆、nat 閘道器,整流器等出現了一些約定俗成的動作。

比如有些防火牆只允許通過 80 和 443,不放通其他埠。nat 閘道器在轉換網路位址時重寫傳輸層的頭部,有可能導致雙方無法使用新的傳輸格式。整流器和中間**有時候出於安全的需要,會刪除一些它們不認識的選項字段。

tcp 協議本來是支援埠、選項及特性的增加和修改。但是由於 tcp 協議和知名埠及選項使用的歷史太悠久,中間裝置已經依賴於這些潛規則,所以對這些內容的修改很容易遭到中間環節的干擾而失敗。

而這些干擾,也導致很多在 tcp 協議上的優化變得小心謹慎,步履維艱。

tcp 是由作業系統在核心西方棧層面實現的,應用程式只能使用,不能直接修改。雖然應用程式的更新迭代非常快速和簡單。但是 tcp 的迭代卻非常緩慢,原因就是作業系統公升級很麻煩。即時通訊聊天軟體開發

現在移動終端更加流行,但是移動端部分使用者的作業系統公升級依然可能滯後數年時間。pc 端的系統公升級滯後得更加嚴重,windows xp 現在還有大量使用者在使用,儘管它已經存在快 20 年。

服務端系統不依賴使用者公升級,但是由於作業系統公升級涉及到底層軟體和執行庫的更新,所以也比較保守和緩慢。

這也就意味著即使 tcp 有比較好的特性更新,也很難快速推廣。比如 tcp fast open。它雖然 2013 年就被提出了,但是 windows 很多系統版本依然不支援它。

不管是 http1.0/1.1 還是 https,http2,都使用了 tcp 進行傳輸。https 和 http2 還需要使用 tls 協議來進行安全傳輸。

這就出現了兩個握手延遲:

1)tcp 三次握手導致的 tcp 連線建立的延遲;

2)tls 完全握手需要至少 2 個 rtt 才能建立,簡化握手需要 1 個 rtt 的握手延遲。

對於很多短連線場景,這樣的握手延遲影響很大,且無法消除。

隊頭阻塞主要是 tcp 協議的可靠性機制引入的。tcp 使用序列號來標識資料的順序,資料必須按照順序處理,如果前面的資料丟失,後面的資料就算到達了也不會通知應用層來處理。

另外 tls 協議層面也有乙個隊頭阻塞,因為 tls 協議都是按照 record 來處理資料的,如果乙個 record 中丟失了資料,也會導致整個 record 無法正確處理。

概括來講,tcp 和 tls1.2 之前的協議存在著結構性的問題,如果繼續在現有的 tcp、tls 協議之上實現乙個全新的應用層協議,依賴於作業系統、中間裝置還有使用者的支援。部署成本非常高,阻力非常大。

所以 quic 協議選擇了 udp,因為 udp 本身沒有連線的概念,不需要三次握手,優化了連線建立的握手延遲,同時在應用程式層面實現了 tcp 的可靠性,tls 的安全性和 http2 的併發性,只需要使用者端和服務端的應用程式支援 quic 協議,完全避開了作業系統和中間裝置的限制。

0rtt 建連可以說是 quic 相比 http2 最大的效能優勢。那什麼是 0rtt 建連呢?

這裡面有兩層含義:

傳輸層 0rtt 就能建立連線;

加密層 0rtt 就能建立加密連線。

tcp 的擁塞控制實際上包含了四個演算法:慢啟動,擁塞避免,快速重傳,快速恢復 [22]。

quic 協議當前預設使用了 tcp 協議的 cubic 擁塞控制演算法 [6],同時也支援 cubicbytes, reno, renobytes, bbr, pcc 等擁塞控制演算法。

從擁塞演算法本身來看,quic 只是按照 tcp 協議重新實現了一遍,那麼 quic 協議到底改進在哪些方面呢?主要有如下幾點。

【可插拔】:

什麼叫可插拔呢?就是能夠非常靈活地生效,變更和停止。體現在如下方面:

1)應用程式層面就能實現不同的擁塞控制演算法,不需要作業系統,不需要核心支援。這是乙個飛躍,因為傳統的 tcp

擁塞控制,必須要端到端的網路協議棧支援,才能實現控制效果。而核心和作業系統的部署成本非常高,公升級週期很長,這在產品快速迭代,網路**式增長的今天,顯然有點滿足不了需求;

2)即使是單個應用程式的不同連線也能支援配置不同的擁塞控制。就算是一台伺服器,接入的使用者網路環境也千差萬別,結合大資料及人工智慧處理,我們能為各個使用者提供不同的但又更加精準更加有效的擁塞控制。比如 bbr 適合,cubic 適合;

3)應用程式不需要停機和公升級就能實現擁塞控制的變更,我們在服務端只需要修改一下配置,reload 一下,完全不需要停止服務就能實現擁塞控制的切換。

stgw 在配置層面進行了優化,我們可以針對不同業務,不同網路制式,甚至不同的 rtt,使用不同的擁塞控制演算法。

【單調遞增的 packet number】:

tcp 為了保證可靠性,使用了基於位元組序號的 sequence number 及 ack 來確認訊息的有序到達。

quic 同樣是乙個可靠的協議,它使用 packet number 代替了 tcp 的 sequence number,並且每個 packet number 都嚴格遞增,也就是說就算 packet n 丟失了,重傳的 packet n 的 packet number 已經不是 n,而是乙個比 n 大的值。而 tcp 呢,重傳 segment 的 sequence number 和原始的 segment 的 sequence number 保持不變,也正是由於這個特性,引入了 tcp 重傳的歧義問題。

quic 的流量控制 [22] 類似 http2,即在 connection 和 stream 級別提供了兩種流量控制。為什麼需要兩類流量控制呢?主要是因為 quic 支援多路復用。

stream 可以認為就是一條 http 請求。

connection 可以模擬一條 tcp 連線。多路復用意味著在一條 connetion 上會同時存在多條 stream。既需要對單個 stream 進行控制,又需要針對所有 stream 進行總體控制。

quic 實現流量控制的原理比較簡單:

通過 window_update 幀告訴對端自己可以接收的位元組數,這樣傳送方就不會傳送超過這個數量的資料。

通過 blockframe 告訴對端由於流量控制被阻塞了,無法傳送資料。

quic 的流量控制和 tcp 有點區別,tcp 為了保證可靠性,視窗左邊沿向右滑動時的長度取決於已經確認的位元組數。如果中間出現丟包,就算接收到了更大序號的 segment,視窗也無法超過這個序列號。

但 quic 不同,就算此前有些 packet 沒有接收到,它的滑動只取決於接收到的最大偏移位元組數。

quic 的多路復用和 http2 類似。在一條 quic 連線上可以併發傳送多個 http 請求 (stream)。但是 quic 的多路復用相比 http2 有乙個很大的優勢。

quic 乙個連線上的多個 stream 之間沒有依賴。這樣假如 stream2 丟了乙個 udp packet,也只會影響 stream2 的處理。不會影響 stream2 之前及之後的 stream 的處理。

這也就在很大程度上緩解甚至消除了隊頭阻塞的影響。

QUIC詳解(基於UDP的低延時網路傳輸層協議)

一 quic 協議概述 quic 全稱 quick udp internet connection 1 快速 udp 網際網路連線 和英文 quick 諧音,簡稱 快 是由 google 提出的使用 udp 進行多路併發傳輸的協議。quic 相比現在廣泛應用的 http2 tcp tls 協議有如下...

C 基於Udp的分包傳輸

因為要遠做程攝像頭監控,要用到網路資料傳輸,了一下,很多就是基於tcp的,因為qq是用udp,所有我也嘗試用udp。要用udp傳輸資料,就免不了分包和重包,因為udp最大只能傳輸64kb的資料!下面給出分包的 首先定義乙個包類 using system using system.collection...

網路詳解 傳輸層(1)UDP 介紹

udp,全名 user datagram protocol,就是使用者資料報協議,是乙個簡單的面向資料報的傳輸層協議。在tcp ip模型中,udp為網路層以上和應用層以下提供了乙個簡單的介面。udp只提供資料的不可靠傳遞,它一旦把應用程式發給網路層的資料傳送出去,就不保留資料備份 所以udp有時候也...