## HTTP/3原理
### 1. **HTTP/3的來源**
由于TCP和UDP兩者在運輸層存在一定差異,TCP的傳遞效率與UDP相比有天然劣勢,于是Google基于UDP開發出了新的協議QUIC(Quick UDP Internet Connections),希望取代TCP提高傳輸效率,后經過協商將QUIC協議更名為HTTP/3。
### 2. **QUIC概述**
TCP、UDP是我們所熟悉的傳輸層協議,UDP比TCP相比效率更高但并不具備傳輸可靠性。而QUIC便是看中UDP傳輸效率這一特性,并結合了TCP、TLS、HTTP/2的優勢,加以優化。
于是在QUIC上層的應用層所運行的HTTP協議也就被稱為HTTP/3。
**HTTP over QUIC is HTTP/3**

## HTTP/3新特性
### 1. **零RTT建立連接**
如下圖,傳統HTTP/2(所有HTTP/2的瀏覽器均基于HTTPS)傳輸數據前需要三次RTT,即使將第一次TLS握手的對稱秘鑰緩存也需要兩次RTT才能傳遞數據。

對于HTTP/3而言,僅僅需要一次RTT即可傳遞數據,如果將其緩存,就可將RTT減少至零。
其核心就是DH秘鑰交換算法。
* 客戶端向服務端請求數據。
* 服務端生成g、p、a三個隨機數,用三個隨機數生成A。將a保留后,將g、p、A(Server Config)傳遞到客戶端。
* 客戶端生成隨機數b,將b保留后,用g、p、b三個隨機數生成B。
* 客戶端再使用A、b、p生成秘鑰K,用K**加密HTTP數據**并與B一同發送到服務端。
* 服務端再使用B、a、p得到相同秘鑰K,并解密HTTP數據。

**至此即可完成一次RTT對連接的建立,當緩存Server Config后零RTT即可進行數據傳遞。**
### 2. **連接遷移**
傳統連接通過源IP、源端口、目的IP、目的端口進行連接,當網絡發生更換后連接再次建立時延較長。
HTTP/3使用Connection ID對連接保持,只要Connection ID不改變,連接仍可維持。

### 3. **隊頭阻塞/多路復用**
* TCP作為面向連接的協議,對每次請求序等到ACK才可繼續連接,一旦中間連接丟失將會產生隊頭阻塞。
* HTTP/1.1中提出Pipelining的方式,單個TCP連接可多次發送請求,但依舊會有中間請求丟失產生阻塞的問題。

* HTTP/2中將請求粒度減小,通過Frame的方式進行請求的發送。但在TCP層Frame組合得到Stream進行傳輸,一旦出現Stream中的Frame丟失,其后方的Stream都將會被阻塞。

* 對于HTTP/2而言,瀏覽器會默認采取TLS方式傳輸,TLS基于Record組織數據,每個Record包含16K,其中有12個TCP的包,一旦其中一個TCP包出現問題將會導致整個Record無法解密。這也是網絡環境較差時HTTP/2的傳輸速度比HTTP/1.1更慢的原因。

* HTTP/3基于UDP的傳輸,不保證連接可靠性,也就沒有對頭阻塞的后果。同樣傳輸單元與加密單元為Packet,在TLS下也可避免對頭阻塞的問題。
### 4. **擁塞控制**
* 熱拔插:TCP對于擁塞控制在于傳輸層,QUIC可在應用層操作改變擁塞控制方法。
* 前向糾錯(FEC):將數據切割成包后可對每個包進行異或運算,將運算結果隨數據發送。一旦丟失數據可據此推算。(帶寬換時間)
* 單調遞增的Packet Number:TCP在超時重傳后的兩次ACK接受情況并不支持的很好。導致RTT和RTO的計算有所偏差。HTTP/3對此進行改進,一旦重傳后的Packet N會遞增。

* ACK Delay
HTTP/3在計算RTT時健壯的考慮了服務端的ACK處理時延。

* 更多地ACK塊
一般每次請求都會對應一個ACK,但這樣也會浪費(下載場景只需返回數據即可)。
于是可設計成每次返回3個ACK block。在HTTP/3將其擴充成最多可攜帶256 個ACK block。
### 5. **流量控制**
TCP使用滑動窗口的方式對發送方的流量進行控制。而對接收方并無限制。在QUIC中便補齊了這一短板。
QUIC中接收方從單挑Stream和整條連接兩個角度動態調整接受的窗口大小。
## 參考資料
[HTTP3](https://juejin.cn/post/6844904182340648967)
- Android
- 四大組件
- Activity
- Fragment
- Service
- 序列化
- Handler
- Hander介紹
- MessageQueue詳細
- 啟動流程
- 系統啟動流程
- 應用啟動流程
- Activity啟動流程
- View
- view繪制
- view事件傳遞
- choreographer
- LayoutInflater
- UI渲染概念
- Binder
- Binder原理
- Binder最大數據
- Binder小結
- Android組件
- ListView原理
- RecyclerView原理
- SharePreferences
- AsyncTask
- Sqlite
- SQLCipher加密
- 遷移與修復
- Sqlite內核
- Sqlite優化v2
- sqlite索引
- sqlite之wal
- sqlite之鎖機制
- 網絡
- 基礎
- TCP
- HTTP
- HTTP1.1
- HTTP2.0
- HTTPS
- HTTP3.0
- HTTP進化圖
- HTTP小結
- 實踐
- 網絡優化
- Json
- ProtoBuffer
- 斷點續傳
- 性能
- 卡頓
- 卡頓監控
- ANR
- ANR監控
- 內存
- 內存問題與優化
- 圖片內存優化
- 線下內存監控
- 線上內存監控
- 啟動優化
- 死鎖監控
- 崩潰監控
- 包體積優化
- UI渲染優化
- UI常規優化
- I/O監控
- 電量監控
- 第三方框架
- 網絡框架
- Volley
- Okhttp
- 網絡框架n問
- OkHttp原理N問
- 設計模式
- EventBus
- Rxjava
- 圖片
- ImageWoker
- Gilde的優化
- APT
- 依賴注入
- APT
- ARouter
- ButterKnife
- MMKV
- Jetpack
- 協程
- MVI
- Startup
- DataBinder
- 黑科技
- hook
- 運行期Java-hook技術
- 編譯期hook
- ASM
- Transform增量編譯
- 運行期Native-hook技術
- 熱修復
- 插件化
- AAB
- Shadow
- 虛擬機
- 其他
- UI自動化
- JavaParser
- Android Line
- 編譯
- 疑難雜癥
- Android11滑動異常
- 方案
- 工業化
- 模塊化
- 隱私合規
- 動態化
- 項目管理
- 業務啟動優化
- 業務架構設計
- 性能優化case
- 性能優化-排查思路
- 性能優化-現有方案
- 登錄
- 搜索
- C++
- NDK入門
- 跨平臺
- H5
- Flutter
- Flutter 性能優化
- 數據跨平臺