QUIC

QUIC是一種通用傳輸層協議，最初由谷歌工程師Jim Roskind提出。該協議於2012年實現並部署，2013年隨著實驗範圍的擴大而公開發布。同時相關人士在IETF會議上就該協議進行說明。雖然其長期處於網際網路草案階段，但從Chrome瀏覽器至谷歌伺服器的連接中，超過一半的連接都使用了QUIC。Microsoft Edge、Firefox都已支持此協議。QUIC於RFC9000中被正式標準化。

QUIC協議名稱最初來源於「快速UDP網際網路連接」（Quick UDP Internet Connection）的首字母縮寫，但在IETF標準中，QUIC不是任何內容的縮寫，而是協議名稱本身。QUIC提高了目前使用TCP的面向連接的網路應用的性能。QUIC基於UDP實現可靠傳輸，在單個連接中支持多個獨立的數據流，並試圖在網際網路傳輸的部分應用場景中替代TCP。

QUIC與HTTP/2的多路復用連接協同工作，允許多個數據流獨立到達所有端點，因此不受涉及其他數據流的丟包影響。HTTP/2雖然支持多路復用，但HTTP/2底層仍依賴TCP，而TCP必須保證字節流按序交付，當TCP連接中的某個數據包丟失時，會導致所有HTTP/2數據流受到隊頭阻塞的影響。

QUIC的次要目標包括降低連接和傳輸時延，以及每個方向的帶寬估計以避免擁塞。此外，該協議還可以擴展前向糾錯（FEC），以進一步提高預期錯誤時的性能，這被視為協議演進的下一步。

2015年6月，QUIC規範的網際網路草案提交給IETF進行標準化。2016年，成立了QUIC工作組。2018年10月，IETF的HTTP工作組和QUIC工作組共同決定將QUIC上的HTTP映射稱為 "HTTP/3"，以提前使其成為全球標準。2021年5月IETF公布RFC9000，QUIC規範推出了標準化版本。

## 背景

傳輸控制協議 (TCP) 旨在為兩個端點之間發送數據流提供一個接口。數據交給TCP系統，TCP系統確保數據以完全相同的形式傳到另一端，否則連接將提示存在錯誤。

為此，TCP將數據分解成網路封包，並在每個數據包中添加少量數據。這些附加數據包括一個序列號，用於檢測丟失或到達順序不正確的數據包，以及一個校驗和，可以檢測數據包數據內的錯誤。當其中任何一個問題發生時，TCP使用自動重傳請求（ARQ）告訴發送方重新發送丟失或損壞的數據包。

在大多數實現中，TCP會將連接上的任何錯誤視為阻塞，停止進一步傳輸，直到錯誤得到解決或連接被視為失敗。如果使用單個連接來發送多個數據流，就像在HTTP/2協議中那樣，所有這些數據流都會被阻止，儘管其中只有一個可能有問題。例如，如果在下載用於收藏夾圖標的GIF圖像時出現一個錯誤，頁面的其餘部分將等待問題得到解決。

由於TCP系統被設計成類似「數據管道」或流，TCP刻意被設計成並不知曉其傳輸的數據之細節。如果對傳輸的數據存在額外需求，如需要使用TLS加密，那麼此類協議必須建立在TCP的上層。每種協議都需要自己的握手過程，結果會導致在建立連接前需要大量交換數據，加之長距離通信的固有延遲，從而給整個傳輸過程增加大量開銷。

## 介紹

QUIC旨在提供幾乎等同於TCP連接的可靠性，但延遲大大減少。它主要通過兩個理解HTTP流量的行為來實現這一點。

第一個變化是在連接建立期間大大減少開銷。由於大多數HTTP連接都需要TLS，因此QUIC使協商密鑰和支持的協議成為初始握手過程的一部分。

當客戶端打開連接時，伺服器響應的數據包包括將來的數據包加密所需的數據。這消除了TCP上的先連接並通過附加數據包協商安全協議的需要。其他協議可以以相同的方式進行服務，並將多個步驟組合到一個請求中。

然後，這些數據既可用於初始設置中的後續請求，也可用於未來的請求。

QUIC使用UDP協議作為其基礎。UDP不包含丟包恢復機制，相反，每個QUIC流是單獨控制的，並且在QUIC級別而不是UDP級別重傳丟失的數據。這意味著如果在某個流中發生丟包或重傳，協議棧仍然可以獨立地繼續為其他流提供服務。

這在提高易出錯鏈路的性能方面非常有用，因為在大多數情況下TCP協議通知數據包丟失或損壞之前可能會收到大量的正常數據，但是在糾正錯誤之前其他的正常請求都會等待甚至重發。

QUIC在修復單個流時可以自由處理其他數據，也就是說即使一個請求發生了錯誤也不會影響到其他的請求。

QUIC包括許多其他更普通的更改，這些更改也可以優化整體延遲和吞吐量。例如，每個數據包是單獨加密的，因此加密數據時不需要等待部分數據包。

在TCP下通常不可能這樣做，其中加密記錄在字節流中，並且協議棧不知道該流中的更高層邊界。這些可以由運行在更上層的協議進行協商，但QUIC旨在通過單個握手過程完成這些。

QUIC的另一個目標是提高網路切換期間的性能，例如當行動裝置的使用者從WiFi熱點切換到行動網路時發生的情況。

當這種情況發生在 TCP 連接上時，會經歷一個較為漫長的過程：已有連接會因為無法繼續通信而逐漸超時，並在需要時重新建立。

為解決此問題，QUIC包含一個連接標識符，該標識符唯一地標識客戶端與伺服器之間的連接，而無論源IP位址是什麼。這樣只需發送一個包含此ID的數據包即可重新建立連接，因為即使使用者的IP位址發生變化，原始連接ID仍然有效。

QUIC在應用程式空間中實現，而不是在作業系統內核中實現。當數據在應用程式之間移動時，這通常會由於上下文切換而調用額外的開銷。

但是在QUIC下協議棧旨在由單個應用程式使用，每個應用程式使用QUIC在UDP上託管自己的連接。最終差異可能非常小，因為整個HTTP/2堆棧的大部分已經存在於應用程式（或更常見的庫）中。

將剩餘部分放在這些庫中，基本上是糾錯，對HTTP/2堆棧的大小或整體複雜性幾乎沒有影響。

QUIC允許更容易地進行未來更改，因為它不需要更改內核就可以進行更新。

QUIC的長期目標之一是添加前向糾錯和改進的擁塞控制。

關於從TCP遷移到UDP的一個問題是TCP被廣泛採用，並且網際網路基礎設施中的許多中間設備被調整為UDP速率限制甚至阻止UDP。

Google進行了一些探索性實驗來描述這一點，發現只有少數連接存在此問題。所以Chromium的網路堆棧同時打開QUIC和傳統TCP連接，並在QUIC連接失敗時以零延遲回退到TCP連接。

### gQUIC與iQUIC

Google 最初開發的 QUIC（通常稱為 gQUIC）於約 2012 年開始部署，隨後提交至 IETF 進行標準化。然而，IETF 標準化後的 QUIC 與 Google 的早期實現存在顯著差異。Google 的 gQUIC 最初是一種面向 Web 的通用協議，主要用於 Chromium 中 HTTP 和 HTTPS 的傳輸，並採用其自有的加密和傳輸機制。相比之下，IETF 在 gQUIC 的基礎上重新設計了 QUIC，將其發展為一種通用傳輸層協議，採用標準 TLS 1.3 完成加密握手，並使用模塊化的數據包和連接設計，以實現更好的互操作性。Chromium 隨後持續跟進 IETF QUIC 的標準化進程，並逐步遷移到符合 IETF 標準的實現。

## 流量控制

與大多數傳輸協議一樣，QUIC 具有流量控制以保護接收端免受緩衝區overflow的影響。QUIC 是基於 UDP 傳輸，而 UDP 沒有流量控制，因此 QUIC 實現了自己的流量控制機制。與TCP不同，QUIC並不是通過ACK確認當前收到的數據編號，而是通過 control frame 實現類似HTTP/2的基於信用的流量控制機制。

## 實現

### 客戶端

Google Chrome於2012年開始開發QUIC協議並且於Chromium版本 29（2013年8月20日釋出）發布。QUIC協議在當前Chrome版本中被默認開啟，活躍的會話列表在`''chrome://net-internals/#quic''`中可見。

### 服務端

截至2017年，有三種活躍維護中的實現。谷歌的伺服器及谷歌發布的 原型伺服器 使用Go語言編寫的 quic-go 及Caddy的試驗性QUIC支持。在2017年7月11日，LiteSpeed科技正式在他們的負載均衡（WebADC）及 LiteSpeed 伺服器中支持QUIC。截止 17 年 12 月， 97.5%的使用 QUIC 協議的網站在 LiteSpeed 伺服器中運行。

另有幾種不再維護的社區產品，基於Chromium實現並且減少使用依賴的 libquic、提供libquic的Go語言綁定的 goquic、打包為Docker鏡像的用來轉換為普通HTTP請求的反向代理 quic-reverse-proxy。

2020年12月，支持DNS-over-QUIC協議的公共DNS解析器，由AdGuard首次公開推出服務。

## 外部連結

- Chromium: QUIC, a multiplexed stream transport over UDP
- QUIC: Design Document and Specification Rationale, Jim Roskind's original document (2012/2013)
- Daniel Stenberg: HTTP/3 explained
- Linux Weekly News: Connecting on the QUIC (2013)
- QUIC: , IETF-88 TSV Area Presentation (2013-11-07)
- Chromium Blog: Experimenting with QUIC (2013)
- QUIC: next generation multiplexed transport over UDP (Google Developers, 2014)
- HTTP over UDP: an Experimental Investigation of QUIC
- Multipath QUIC (extension to QUIC)
- Innovating Transport with QUIC: Design Approaches and Research Challenges (2017)
- Does my browser support HTTP/3 & QUIC? - Cloudflare

## 基本資料

- 開發者：IETF, Google
- 日期：2012年10月12日
- 原型：IP, UDP
- osilayer：傳輸層