在正式介紹協定本身之前,還是要先做一下背景介紹,雖然前兩天的文章有簡單提到了,但今天的議題還是來深入探討一下 TCP 有什麼問題,HTTP/3 會選擇棄用 TCP 呢?
上圖是 google 論文中提供的參考資料,可以看到越來越多服務開始採用 HTTPS,但是在優化連線速度的時候發現常常效能瓶頸會在 TCP + TLS 的環節,過去已經有無數的人想要嘗試優化 TCP,發展新的技術,但其實可以觀察到網際網路的環境其實受限於一些硬體限制,或者成本考量,新技術的普及率往往推廣的很慢,可能基於成本考量,採用新技術的成本遠高於帶來的收益等等。
很多革新的技術推廣失敗的主因其實不是演算法或者性能差距,而是受到硬體的限制。整個 Internet 建立在無數的硬體設備上,協助一端把封包傳送到另一端。其中會經過像是防火牆,NAT,loda balancer 等等,這些設備被統稱為 Middlebox。
也許是因為基於 TCP 的生態系已經經過了時間的驗證,讓很多 middlebox 都以穩定為優先事項,不知不覺之間發展出一套"潛規則",像是有些防火牆只允許特定的 port 的流量通過,或者 NAT 會修改部份的 Header 資料,這些設計完全契合了長期穩定的生態系,但也延伸出一個問題: 協定僵化。一些實驗性的 option 放入 Header 之中,可能也會被判定是惡意流量而慘遭丟棄。
上述說的很多 Middlebox 可能在設計之初也不會考慮到擴充性的問題,即使提出一個新的革命性的技術,如果硬體本身無法支援的話,那技術終究只能淪為只存在論文中的學術產物或者只能在特定場景使用的非通用技術。更換硬體需要大量的成本,如果誘因不足,普及率自然沒辦法拉高。
reference: 協定僵化
一般來說 TCP 都實現在 kernel space,並且應用程式不能直接修改,這也是 TCP 迭代速度緩慢的原因之一,os 的升級牽扯到各種不同的模組,要經過層層的審核測試,比起快速迭代新功能,在 kernel 的 TCP 更重視穩定。
現代應用程式更想要一個可以靈活調整的協定,根據自己的需求可以調整擁塞控制演算法策略等,所以自然而然想到把 QUIC 實現在 user space。
很多 request 都是短連結,單次任務結束就會關掉連線,這時候大部分的時間都會耗費在 Handshake 的環節,甚至比 request 拿資源的時間還久,更不用提現代應用基本綁定了 TCP + TLS 的組合,會比單純 TCP 消耗更多的時間在 Handshake,降低建立連線的時間也是一個非常重要的議題,甚至可以說是 QUIC 發展的目的之一。
過往很多技術都想方設法加快 TCP 的交握流程,像是 TCP Fast Open - RFC7413,但就如同上面兩點所述,TCP 的更新以及推廣會受到很多限制,2014 提出的 TCP Fast Open 到現在也沒有被所有的人採納,由此可見 TCP 的確穩定,但是不利於革新,歷史包袱太過沈重了。
這個議題後面會詳細敘述,這邊就簡單提一下。
定義: When a single (slow) object prevents other/following objects from making progress.
可以理解成塞車,單線道有台很慢的車會拖慢整體速度,讓後面的車子停滯不前。
HTTP/2 在基於 TCP 的連線的示意圖如上圖,僅靠單個連線在應用程式的層級支援 multiplexing,看似解決了 HOL 問題,但是如果是 TCP 傳輸的時候掉封包導致的重傳,這樣會導致 TCP 層級的隊頭阻塞,牽連到上層 HTTP/2 的運作情形。
reference
TCP隊頭阻塞
Head-of-Line Blocking in QUIC and HTTP/3: The Details