QUIC 是跑在 UDP 上的通用传输协议,它把传输握手与 TLS 1.3 合并成一次交互,HTTP/3 就架在它上面。MDN 的术语页把它概括为「UDP 上的多路复用传输协议」。本文按 RFC 9000、9001、9002、9114 的条款拆三件事:连接怎么建立、连接怎么跟着设备换网、丢包怎么判定,再逐个纠正五个常见说法。
握手为什么能压到 1-RTT
在 TCP 上跑 HTTPS,客户端要先用一个往返完成三次握手,再花一个往返做 TLS 1.3 完整握手,应用数据得等到第二个往返结束才发得出去。QUIC 把 TLS 1.3 装进自己的 CRYPTO 帧,客户端首包(Initial)就带着 ClientHello,服务器在一个往返内回完 ServerHello、证书与 Finished。
客户端拿到 1-RTT 密钥后就能发请求,所以新建连接是一个往返而不是两个。省下的是协议分层带来的重复,不是加密强度:1-RTT 密钥仍由 TLS 1.3 的密钥调度导出,包格式与握手状态机写在 RFC 9000 第 7 节。
再次访问同一站点时,客户端手里有会话票据,可以在首包就附上 0-RTT 数据,把建立连接的这个往返也省掉。代价写在 RFC 9001 里:0-RTT 数据不具备重放保护(第 5.6 节写作 lack of replay protection,第 9.2 节专讲重放攻击)。
服务器可以接受也可以拒绝 0-RTT(RFC 9001 第 4.6.2 节),被拒后客户端要把数据换到 1-RTT 重发。所以它只适合幂等请求,下单、支付一类动作不该塞进去。
| 阶段 | TCP + TLS 1.3 | QUIC |
|---|---|---|
| 传输握手 | 1 个往返(SYN、SYN-ACK、ACK) | 与 TLS 合并进行 |
| 加密握手 | 再 1 个往返 | 同一次往返内完成 |
| 首次可发应用数据 | 约 2 个往返 | 约 1 个往返 |
| 再次连接 | 1 个往返,另需 0-RTT 数据通道 | 首包即可带 0-RTT 数据 |
| 地址校验 | 无内建机制 | 验证前回包不超过已收字节的 3 倍(RFC 9000 第 8.1 节) |
握手省下的往返只影响连接建立,传输语义并未改变。缓存、条件请求、重定向这些规则照旧,配置思路可参考站内那篇HTTP 缓存怎么配。连带的变化只有一点:Alt-Svc 响应头成了发现新协议的入口,这点在后文回退部分再说。
连接迁移为什么靠 Connection ID
TCP 用四元组标识一条连接,IP 一变连接就作废,只能重连。QUIC 把连接身份放在 Connection ID 上,长度 0 到 20 字节(RFC 9000 第 5.1 节),接收端按 CID 找到对应连接(第 5.2 节),与源地址解耦。
手机从 Wi-Fi 切到蜂窝网络时,客户端在新路径上发非探测包即视为发起迁移(第 9.2 节)。服务端收到陌生地址的包,先做路径验证(第 8.2 节):发 PATH_CHALLENGE,等对方回 PATH_RESPONSE(第 19.17、19.18 节),通过后才把发送地址切过去。
迁移不是免费的。第 9.4 节要求切到新路径后重置拥塞控制与 RTT 估计,因为旧路径的带宽和时延不能外推;新路径的路径 MTU 也要重新探测。NAT 重绑定看起来像迁移,但客户端并不知道自己地址变了,两种情况在服务端要分开统计。
另外,CID 长度为零时无法用它区分连接,迁移能力受限,多条连接共用同一四元组也不成立。第 9.5 节还提醒,迁移会把地址变化暴露给观察者,及时换发新 CID 能减少这种关联。
服务端也可以在握手时下发首选地址(第 9.6 节),让客户端在连接建立后迁到更合适的入口。多机房接入时,这比只靠 DNS 轮询更可控,因为迁移时机由连接双方掌握。
包号、ACK 与丢包检测

QUIC 的包号是 0 到 2 的 62 次方减 1 之间的整数(RFC 9000 第 12.3 节),Initial、Handshake、Application 三个包号空间各自独立编号。包号本身受头部保护加密(RFC 9001 第 5.4 节),链路上的中间设备难以据此做流量分析。
QUIC 从不重传同一个包号:重传是发一个新包号的新包。这样 ACK 就能无歧义地对应到某一次发送,RTT 采样不会被重传搞混,这是它与 TCP 的一个关键差别。
ACK 帧用区间列表确认收到的包,允许乱序到达。丢包判定有两条独立路径(RFC 9002 第 6.1 节):一是包阈值,同一空间里某个包之后有 3 个包被确认就判丢(第 6.1.1 节,kPacketThreshold 推荐值 3)。二是时间阈值,早于 9/8 乘以 max(smoothed_rtt, latest_rtt) 且不小于 1 毫秒(第 6.1.2 节)。
ACK 迟迟不来时,发送端靠探测超时打破僵局:超时后补发一两个探测包,而不是立刻把整个窗口重传一遍(第 6.2 节)。探测间隔按平滑 RTT 与方差推算,连续超时会翻倍,直到重新收到确认。
两条路径任一成立即判丢,之后由拥塞控制决定还能发多少(第 7 节)。拥塞控制按路径计,所以换路径要重置,这与迁移的代价是同一条约束。具体算法怎么取舍,可对照站内CUBIC 与 BBR 的对比,QUIC 只是把这份状态搬到了用户态。
QUIC 的五个常见说法逐个纠正
- 「QUIC 一定更快」:省下的是新建连接的那一个往返,连接一旦复用,这点差距就被摊销掉了。Cloudflare 的 HTTP/3 介绍也把收益归到握手合并与丢包隔离这两处。收益集中在弱网丢包、频繁切网、首屏请求少的场景;服务端在用户态做加解密,CPU 开销与内核 TCP 不同,换协议前要单独压测。
- 「QUIC 用 UDP,所以不可靠」:可靠性在 QUIC 内部实现,包号、ACK、重传、按流有序交付都由它自己做,UDP 只是承载。丢包只阻塞所属的那条流,其余流继续推进(RFC 9114 第 2 节)。
- 「UDP 被封,QUIC 就用不了」:RFC 9308 第 2 节引用的测量显示,3% 到 5% 的网络封掉全部 UDP。所以部署必须留回退:用 Alt-Svc 通告 HTTP/3(RFC 9114 第 3.1.1 节),失败回落到 TCP 上的 HTTP/2。UDP 端口策略与隧道经验可对照站内WireGuard 的握手与 AllowedIPs。
- 「0-RTT 没有代价」:它可以被重放,服务器也有权拒绝(RFC 9001 第 4.6.2 节与第 9.2 节)。把它当优化而不是默认,只给幂等读请求用,被拒时要有重发路径。
- 「HTTP/3 消灭了队头阻塞」:它只消除了传输层的。QPACK 动态表仍会让流阻塞,RFC 9204 第 2.1.2 节规定解码器遇到尚未收到的表项时该流被判为 blocked;控制流丢包也会拖慢整条连接。
运维与开发的落地建议
先看服务端。同时开 HTTP/2 与 HTTP/3,Alt-Svc 的 max-age 不要设得过长,回退路径要真能跑通,而不是只在配置里写一笔。
- 防火墙放行 HTTP/3 使用的 UDP 端口,并检查有状态设备对 UDP 会话的老化时间,别让空闲连接被提前清掉。
- 负载均衡按 CID 路由,RFC 9000 第 5.2.3 节给了简单均衡器的考虑要点;否则迁移后的包会落到错的实例。
- 观测侧分开统计三个包号空间的丢包与探测超时,区分 NAT 重绑定和主动迁移。
- 客户端重试要幂等,移动端专门测切网;0-RTT 被拒时确认还有 1-RTT 的重发分支。
把这几件事分开看,收益和代价就都能算清楚:QUIC 买到的是一个往返、一次可验证的迁移、一套更清晰的丢包信号,付出的是用户态开销与更复杂的部署面。若你的站点以短连接、移动端为主,先把回退和观测补齐,再谈切换。
相关地址
以下为文中引用的标准与文档入口,条款号与字段名以这些页面为准。
- RFC 9000(QUIC 传输协议):https://www.rfc-editor.org/rfc/rfc9000.html
- RFC 9001(TLS 在 QUIC 中的使用):https://www.rfc-editor.org/rfc/rfc9001.html
- RFC 9002(QUIC 丢包检测与拥塞控制):https://www.rfc-editor.org/rfc/rfc9002.html
- RFC 9114(HTTP/3):https://www.rfc-editor.org/rfc/rfc9114.html
- RFC 9204(QPACK 头字段压缩):https://www.rfc-editor.org/rfc/rfc9204.html
- RFC 9308(QUIC 适用性说明):https://www.rfc-editor.org/rfc/rfc9308.html
- Cloudflare 学习中心:What is HTTP/3?:https://www.cloudflare.com/learning/performance/what-is-http3/
- MDN Web Docs 术语表:QUIC:https://developer.mozilla.org/en-US/docs/Glossary/QUIC
© 版权声明
文章版权归作者所有,转载需注明出处。未声明原创的皆为网络收集,如有侵权请邮箱lishiwenhuagx@sina.com联系下架处理。




