1) 拥塞控制(Congestion Control)
目标:像 TCP 一样“探测网络容量、避免拥塞”,但在用户态、按 QUIC 的包与确认模型运行。
-
算法:QUIC 不强制具体算法,常见是 CUBIC 或 BBR。实现里维护
cwnd、bytes_in_flight、ssthresh等与 TCP 同名/同义的变量。 -
慢启动 & 拥塞避免:新路径或恢复后进入慢启动,指数增长
cwnd;丢包或 ECN 指示拥塞时进入拥塞避免/减小cwnd。 -
丢包信号来自 ACK 与时间:
- ACK Ranges 报告多个区间已收包,帮助快速判断哪些包“明显落后”而推定丢失。
- PTO (Probe Timeout) :无 ACK 时触发探测性超时(类似 TCP 的 TLP/RACK 思路),发送“探测包”来唤醒对端/重同步 RTT 估计。
-
包速率整形 (Pacing) :按估计带宽对发送速率做抖动/间隔(配合 BBR 效果显著),降低突发。
-
ECN:如路径支持 ECN,拥塞信号可来自标记而非丢包,减少不必要重传。
-
路径层面:每条 Path(五元组/IP 变化) 有独立的 RTT、
cwnd、丢包统计;迁移或多路径时分别管理。
直观理解:拥塞控制的“数学”和 TCP 类似,但 QUIC 自己掌握发送/确认语义,所以能更快得到更丰富的信号(ACK ranges/ack delay/不同号位空间),并且易于在用户态迭代算法。
2) 丢包检测与恢复(Loss Detection)
核心与 TCP 不同点:QUIC 把包编号、确认、重传做了更多结构化设计。
-
包号空间 (Packet Number Spaces) :分 Initial / Handshake / 0-RTT / 1-RTT 四个独立空间,互不影响丢包/计时器。握手阶段丢包不会拖累应用数据空间。
-
ACK Ranges + ACK Delay:对端一次 ACK 可汇报多个已收区间,并带上延迟,发送端用它来:
- 精准推断“间隙”区间为丢包;
- 估计 RTT(min/ smoothed / variance)。
-
不做“重传同号” :QUIC 不重用包号。重传 = 发送全新的包携带还未被确认的帧(frame)。这避免了“哪一份才是重传”的歧义,也更利于拥塞/统计。
-
PTO/Probe 包:当 ACK 长时间缺失,发送端发探测数据(通常携带 PING、少量应用数据或流量控制更新)来重建时钟与拿回 ACK。
-
Spin Bit(可选) :为测量 RTT 暴露一个比特(运营商/测量用),不影响协议安全。
3) 流量控制(Flow Control)
目标:避免发送方“淹没”接收方内存;QUIC采用“信用额”模式,分两层限额:
- Connection-level:整条连接的总可接收字节额度(
MAX_DATA通告)。 - Stream-level:每条流(Stream)的可接收额度(
MAX_STREAM_DATA)。
工作方式(信用驱动 / 拉式):
- 接收端消耗数据后,按消费进度通过
MAX_DATA/MAX_STREAM_DATA增加额度(发放更多 credit)。 - 发送端若达到额度上限,必须等待
MAX_*更新。 - 若被卡住可通告
DATA_BLOCKED/STREAM_DATA_BLOCKED让对端知悉是流控阻塞而非拥塞。 - 按流/按连接双限 → 既避免单流霸占内存,也防止总量失控。
4) 加密与握手(TLS 1.3 内嵌)
最大差异:QUIC 把 TLS 1.3 直接嵌入传输层(不是“先 TCP 再 TLS”),握手与密钥推导直接驱动包加密。
-
密钥阶段:
- Initial:用版本固定 salt + 对端 DCID 通过 HKDF 派生“初始密钥”(加密 ClientHello 等 CRYPTO 帧)。
- Handshake:握手推进,拿到证书/完成密钥交换,切换到更强密钥。
- 1-RTT:握手完成后进入应用数据密钥;支持 Key Update 轮换。
-
0-RTT:会话复用时可用 0-RTT 密钥“立刻发数据”,可重放,应用层需限制在幂等/安全语义(例如禁写操作或带 anti-replay 策略)。
-
AEAD 算法:AES-GCM 或 ChaCha20-Poly1305;包头保护 (Header Protection) + 载荷加密,中间盒看不到明文序号与帧类型(抗劫持/篡改)。
-
握手往返:首连 1-RTT;复用 0-RTT。相比 TCP+TLS(1.2/1.3) 的多次 RTT,显著降低建连时延。
-
CRYPTO 帧:TLS 握手消息被装进 QUIC 的 CRYPTO 帧里在相应号位空间传输(Initial/Handshake)。
5) 流多路复用(Streams)与无 HOL
- 独立的有序字节流:每个流自带偏移序号与 FIN,按需有序;不同流之间互不等待。
- 帧类型:
STREAM携带应用数据;RESET_STREAM终止、STOP_SENDING请求对端停发、MAX_STREAMS调控“可并发打开的流数”。 - 无 HOL:某流丢包只影响该流;其他流在同一连接上继续前进,这正是 HTTP/3 消除 TCP 层 HOL 的根本。
6) 连接迁移、路径验证与放大攻击防护
- Connection ID (CID) :连接与 5 元组解耦。IP/端口变化(Wi-Fi ↔ 5G)不需要重连;换路由器也能无缝继续。
- Path Validation:新路径探测(
PATH_CHALLENGE/PATH_RESPONSE)确认可达与反射地址合法性。 - 反放大 (Anti-Amplification) :在对端地址未验证前,服务器发包总字节受限于收到字节的 3 倍,避免被用于放大攻击。
- Retry & NEW_TOKEN:在握手早期做地址验证;服务端可发
Retry让客户端带 token 回来证明“可达/属地”。 - Stateless Reset:当状态丢失或遭异常,服务端能以短小难以伪造的报文让客户端快速察觉“连接已失效”。
7) 报文结构与传输细节
- UDP 报文里可 合并多个 QUIC 包(coalescing),例如同时带 Initial 与 Handshake,减少往返。
- 每个包可携带 多个帧(
STREAM、ACK、MAX_DATA、PING、CRYPTO…),灵活复用带宽。 - DPLPMTUD:基于数据报的 PMTU 探测,逐步提高有效载荷,避免 IP 分片。
- 优先级:HTTP/3 用优先级信号(独立于 QUIC)指导发送器如何在多流间分配带宽。
- QPACK(HTTP/3 头压缩) :为避免 HPACK 的“压缩状态阻塞”,解耦了头部动态表的更新与引用,配合 指令流 实现无 HOL 的头压缩。
8) 与 TCP 的关键对照(为什么更快更稳)
| 能力 | TCP(+TLS) | QUIC |
|---|---|---|
| 握手 | 3WH + TLS(1–2 RTT) | 1-RTT(首连)/ 0-RTT(复用) |
| 多路复用 | 应用层;受 TCP HOL | 传输层本地能力;无 HOL |
| 丢包恢复 | 全连接顺序交付 | 按流独立、号位空间独立、PTO |
| 升级/演进 | 内核协议、慢 | 用户态库、可快速试验 CUBIC/BBR/QLog |
| 迁移 | 基于 5 元组,变更即断 | CID 跨网不掉线 |
| 加密 | 叠加到 TCP 之上 | 内置 TLS 1.3、头保护 |
9) 开发与运维关注点
- 0-RTT:小心可重放;只用于幂等读请求或经应用层令牌/时间窗防护。
- 观测:启用 qlog/qrt 与服务端指标(PTO 次数、RTT/RTTv、cwnd、丢包率、path 切换次数)。
- 中台/网络设备:因为端到端加密更彻底,传统中间盒 L7 可见性下降;需配合可观测方案与边缘代理更新。
- 版本/Key Update:长连接场景下定期 Key Update,平滑滚动;留意老路径残留包的处理。
- PMTU:生产环境建议启用 DPLPMTUD,禁 IP 分片。
一句话总结
QUIC 把“TCP 做的事”搬到用户态并重做了一遍:拥塞控制/丢包恢复更灵活、流量控制更细粒度、加密与握手更快、按流无 HOL、连接可迁移。这就是 HTTP/3 能在高丢包、移动网络下明显更稳更快的根因。