推薦閱讀:
HTTP/3
竟然是基於UDP
的!開始我也很疑惑,UDP
傳輸不可靠,沒有擁塞機制,究竟怎麼操作呢?
先說解決方案:
QUIC(Quick UDP Internet Connection)是谷歌制定的一種基於UDP的低時延的網際網路傳輸層協議 !
QUIC很好地解決了當今傳輸層和應用層面臨的各種需求,包括處理更多的連線,安全性,和低延遲。
前言
有關於 TCP 和 UDP “連線”這個詞,是一個邏輯中的“虛擬”的概念,是為了方便我們的學習理解。
UDP的無連線,TCP的連線,唯區別是,UDP把只管傳送,TCP每次都對傳送的資料進行ACK確認。
這部分程式碼是放在傳輸層,還是放在應用層,這都關係不大。
QUIC是可以獨立於作業系統發行的,避免了作業系統緩慢的更新換代問題。
QUIC依然要面對訊息的可靠性、滑動視窗、擁塞控制等問題,你可以認為它就是一個TCP(但是本質不一樣)。
Chromium 官方宣佈 Chrome正在部署到 HTTP/3 與IETF QUIC。
為什麼轉用UDP?
因為TCP本身非常複雜,並且有太多歷史遺留的包袱。
TCP協議,目前已經被編碼到了作業系統,不論是協議升級,還是Bug修復,都是一個大工程。
選擇了UDP
, UDP是一張白紙,它只是IP協議的一個程式設計介面。
-
HTTP3創造出Connection ID概念實現了連線遷移,通過融合傳輸層、表示層,既縮短了握手時長,也加密了傳輸層中的絕大部分欄位,提升了網路安全性。
-
HTTP3在Packet層保障了連線的可靠性,在QUIC Frame層實現了有序位元組流,在HTTP3 Frame層實現了HTTP語義,這徹底解開了隊頭阻塞問題,真正實現了應用層的多路複用。
-
QPACK使用獨立的單向Stream分別傳輸動態表編碼、解碼資訊,這樣亂序、併發傳輸HTTP訊息的Stream既不會出現隊頭阻塞,也能基於時序性大幅壓縮HTTP Header的體積。
HTTP/3解決了那些問題?
-
HTTP3基於UDP協議重新定義了連線,在QUIC層實現了無序、併發位元組流的傳輸,解決了隊頭阻塞問題(包括基於QPACK解決了動態表的隊頭阻塞);
-
HTTP3重新定義了TLS協議加密QUIC頭部的方式,既提高了網路攻擊成本,又降低了建立連線的速度(僅需1個RTT就可以同時完成建鏈與金鑰協商);
-
HTTP3 將Packet、QUIC Frame、HTTP3 Frame分離,實現了連線遷移功能,降低了5G環境下高速移動裝置的連線維護成本。
隊頭阻塞問題
HTTP2協議基於TCP有序位元組流實現,因此應用層的多路複用並不能做到無序地併發,在丟包場景下會出現隊頭阻塞問題。
HTTP3採用UDP作為傳輸層協議,重新實現了無序連線,並在此基礎上通過有序的QUIC Stream提供了多路複用。
QPACK編碼
與HTTP2中的HPACK編碼方式相似,HTTP3中的QPACK也採用了靜態表、動態表及Huffman編碼。
HTTP/2 沒使⽤常⻅的 gzip 壓縮⽅式來壓縮頭部,⽽是開發了 HPACK 演算法,HPACK 演算法主要包含:
- 靜態字典;(高頻頭部或者欄位,共61種,QPACK中,則上升為98個靜態表項)
- 動態字典;(自行構建。Index 62 起步)動態表編解碼方式差距很大
- Huffman 編碼 編碼(壓縮演算法);
客戶端和伺服器兩端都會建⽴和維護「字典」,⽤⻓度較⼩的索引號表示重複的字串,再⽤ Huffman 編碼壓縮資料,可達到 50%~90% 的⾼壓縮率。
動態表就是將未包含在靜態表中的Header項,在首次出現時加入動態表,這樣後續傳輸時僅用數字表示,大大提升了編碼效率。
因此,動態表是天然具備時序性的,如果首次出現的請求出現了丟包,後續請求解碼HPACK頭部時,會被阻塞。
QPACK將動態表的編碼、解碼獨立在單向Stream中傳輸,僅當單向Stream中的動態表編碼成功後,接收端才能解碼雙向Stream上HTTP訊息裡的動態表索引。
IOT
物聯網時代,移動裝置接入的網路會頻繁變動,從而導致裝置IP地址改變。
對於通過四元組(源IP、源埠、目的IP、目的埠)定位連線的TCP協議來說,這意味著連線需要斷開重連。
而HTTP3的QUIC層允許移動裝置更換IP地址後,只要仍保有上下文資訊(比如連線ID、TLS金鑰等),就可以複用原連線。
-
Packet Header實現了可靠的連線。
-
QUIC Frame Header在無序的Packet報文中,基於QUIC Stream概念實現了有序的位元組流,這允許HTTP訊息可以像在TCP連線上一樣傳輸;
-
HTTP3 Frame Header定義了HTTP Header、Body的格式,以及伺服器推送、QPACK編解碼流等功能。
為了進一步提升網路傳輸效率,Packet Header又可以細分為兩種:
-
Long Packet Header用於首次建立連線;
-
Short Packet Header用於日常傳輸資料。
參考
- https://tools.ietf.org/html/draft-ietf-quic-http-34
- https://tools.ietf.org/html/draft-ietf-quic-transport-34#section-17
- https://ably.com/topic/http3?amp%3Butm_campaign=evergreen&%3Butm_source=reddit&utm_medium=referral
- https://www.nginx.org.cn/article/detail/422
- https://www.chinaz.com/2020/1009/1192436.shtml