QUIC 协议
上一节末尾留了两个悬念:QUIC 凭什么把"TCP 握手加 TLS 握手"压成一次?手机从 WiFi 切到 5G,视频通话为什么能不断线?这两个问题对应着 QUIC 的两招招牌绝活——握手合并(快)与连接迁移(稳)。但只把它们当成"两个新功能"就小看 QUIC 了:这两招绝活背后是同一次身份革命——TCP 用"你在哪个门牌、走哪个门"(IP 和端口)认人,QUIC 改用一张"会员卡"(Connection ID)认人。身份换了定义方式,快和稳都只是它的副产品。本节把这场革命从头讲到尾,顺便诚实交代 QUIC 的代价——它不白快,CPU 和电池都在替它买单。
你正打着视频电话从办公楼走向地铁站。出楼门那一瞬,手机从办公室 WiFi 切到 5G——屏幕上的通话卡住、黑屏、转圈,三秒后才恢复,对面朋友问你"刚才掉线了?"你说"嗯,出楼了"。
这三秒里发生了什么?老协议(TCP)的逻辑是:连接的身份 = 你出发的门牌号 + 你走的门 + 对方的门牌号 + 对方的门。四个要素绑死成一个身份。你从 WiFi 搬进 5G,等于"门牌号"当场换了——在 TCP 眼里,你不是一个换了地址的熟人,而是一个凭空消失的陌生连接。它只能等超时、重连、重新握手、重新对暗号,一切从头再来。
换成 QUIC 的世界,同样一部手机、同样一出电梯:通话没有任何感觉。因为 QUIC 认人不认地址——连接的身份是一张"会员卡号",你换衣服(换 WiFi)、换住址(换基站)、换手机号(换 IP),卡号不变,服务器就永远知道"还是你"。这就是本节的主角戏码:把身份从"地址"上剥下来。
先把这一节的术语翻译成人话
本节术语环环相扣,建议先扫一遍表,正文里再遇到就有印象了:
| 术语 | 翻译成人话 | 生活原型 |
|---|---|---|
| RTT(往返时延) | 一问一答跑一个来回的时间 | 朝对面山头喊话听回声 |
| 握手 | 正式通话前互对暗号、建规矩 | 接暗号的接头双方 |
| 0-RTT / 1-RTT | 开口第一句就带正事 / 一轮暗号后才办事 | 熟客刷脸直接点单 |
| 重放攻击 | 坏人把你说过的话原样再说一遍 | 录音重复播放"转账吧" |
| 四元组 | TCP 认人的四要素:双方 IP+双方端口 | 门牌号+门牌号+门+门 |
| Connection ID | QUIC 的连接会员卡号,与地址无关 | 健身房会员卡 |
| 连接迁移 | 地址变了连接不断 | 搬家不改会员卡 |
| NAT | 家里多台设备共用一个公网地址的机制 | 一栋楼共用一个总机 |
| 用户态 / 内核态 | 普通软件的地盘 / 操作系统心脏的地盘 | 沿街商铺 / 大院内部 |
| 幂等 | 同一件事做一次和做十次效果相同 | 电梯按十次开门键 |
先算一笔账:握手到底贵在哪
要体会 QUIC 的"快"有多值钱,得先弄明白老协议到底慢在哪笔账上。而这笔账的核心,是一个网络世界的硬通货——RTT(Round-Trip Time,往返时延):你发一句话到对方、对方回一句话到你,一个来回的总时间。
RTT 的下限由物理定律写死:光速。北京到纽约一万三千公里,光在光纤里跑(速度约为真空的三分之二),单程约 65 毫秒,一个来回约 130 毫秒——哪怕全世界设备零延迟,这个 130 毫秒也省不掉。国内跨个省,RTT 大概十几到几十毫秒;同一座城里,几毫秒。听着都不长?可握手是"问一句、等一句"的串行流程,每多一个来回,就多付一次全额 RTT,而这些毫秒全部发生在你看到网页第一个像素之前。
现在算老账本。用 HTTPS 走 TCP + TLS 1.2(上一代加密协议),首次访问一个美国网站:TCP 三次握手要一个 RTT(§ 3.2 讲过:你问"在吗"、它答"在,你还在吗"、你答"在"——从你的角度,发完第一句到收到第二句,正好一个来回);TLS 1.2 的完整握手再加两个 RTT;然后才轮到 HTTP 请求再花一个 RTT。四个来回,约 520 毫秒,全部是"铺垫"——此时屏幕上还什么都没有。相当于你下馆子,点菜之前先得跟服务员互相介绍三轮。这就是为什么早期 HTTPS 让人觉得"比 HTTP 慢":不是加密本身慢,是暗号对得太啰嗦。
这笔账画成时序图,四种技术的差距一目了然——从上往下是三十年的提速史:
【TCP + TLS 1.2 · 1990s 组合】 【TCP + TLS 1.3 · 2018】
你 ──在吗?──→ 服务器 你 ──在吗+加密提案──→ 服务器
你 ←─在,你还在?── 服务器 你 ←─在+应答密钥── 服务器
你 ──在──→ 服务器 你 ──GET 页面──→ 服务器
你 ──加密参数──→ 服务器 你 ←─页面内容── 服务器
你 ←─加密应答── 服务器 ↓ 3 个来回(3×RTT)
你 ──密钥确认──→ 服务器 【QUIC 首访 · 2021】
你 ←─密钥确认── 服务器 你 ──建连接+加密提案──→ 服务器
你 ──GET 页面──→ 服务器 你 ←─连接成立+密钥── 服务器
你 ←─页面内容── 服务器 你 ──GET 页面──→ 服务器
↓ 4 个来回(4×RTT) 你 ←─页面内容── 服务器
↓ 2 个来回(2×RTT)
【QUIC 回访 · 0-RTT】
你 ──GET 页面+会员卡──→ 服务器
你 ←─页面内容── 服务器
↓ 1 个来回(1×RTT)
对着图再补一笔"心理账":人对等待的忍耐不是线性的。100 毫秒内响应感觉是"即刻";1 秒开始不耐烦;3 秒是大量用户关闭页面的临界线。也就是说从 4 个来回压到 1 个来回,在跨洋访问(RTT 130 毫秒)的账面上是省了约 400 毫秒——听起来只是一顿饭前的零头,但在"接近即刻"和"开始不耐烦"之间,这 400 毫秒可能正好横跨分界线。握手优化的终极意义不在省时间,在跨过体感的门槛。
前置功劳:TLS 1.3 先砍了一刀
QUIC 的故事不是从零开始的,它的第一个节省来自TLS 1.3(2018 年定稿,§ 4.4 提过它是握手提速的功臣)。TLS 1.2 的握手为什么这么啰嗦?因为它的规矩是"先认识、再商量怎么加密、最后才能带正事"——三轮对话,一步不能省。TLS 1.3 的脑洞是:既然现代密码学允许"第一句话就自带加密参数",那商量加密的那一轮干脆砍掉。你开口的第一句话里直接带上自己的加密提案,对方点头,加密就成立了——完整握手从两个 RTT 压到一个。
这就把 HTTPS 首访的总账从四个来回砍到三个(TCP 一个 + TLS 一个 + 请求一个)。但注意,TLS 1.3 的刀再快,也砍不到 TCP 那一个 RTT——因为握手是在连接建立之后才开始的,两层各对各的账,谁也替谁省不了。天花板就在这儿摆着:只要 TCP 和 TLS 还是两张皮,握手就永远是"两段式"。打破这个天花板,需要的不只是优化,而是合体——这正是 QUIC 登场的台词。
合并握手:一次寒暄,两件事全办完
QUIC 的第一招绝活,说穿了就一句话:把"建立连接"和"协商加密"合成同一轮对话。你开口的第一句 QUIC 消息,既包含"我要建连接"的传输层内容,也包含 TLS 1.3 的加密提案——两个部门的工作合并成一张表格,跑一次流程盖两个章。对方回一句,连接成立、加密也成立。首访握手:一个 RTT,完毕。说白了,这是"部门合并"省下的时间,不是"跑得更快"省下的时间——路还是那条路,只是过安检的队伍从两队并成了一队。
这一招为什么 TCP 永远学不会?不是工程师没想到,是身份决定命运。TCP 诞生于 1981 年,那时候加密根本不是它的业务范围——它是"运输队",只管把字节搬到,搬的对错它都不问,更别提搬的内容要不要保密。后来 HTTPS 时来了,只能在 TCP 之上再叠一层 TLS,两层各握各的手。而 QUIC 是 2010 年代重新设计的,设计图纸上加密就是承重墙(上一节说过:安全织进基因)——既然加密是与生俱来的,握手自然一次就够。打个比方:老饭店的前台和安保是两个部门,客人要分别登记两次;新饭店开业那天就把安保台并进了前台——办一张房卡,登记和安检同时完成。
0-RTT:熟客刷脸,进门就点单
首访一个 RTT 已经很快了,但 QUIC 对回头客还有更狠的一招:0-RTT——零往返。名字听着玄,其实就是熟客逻辑:第一次来,你跟店里办了张会员卡(上次连接结束时,双方交换了一个"会话恢复凭证",存在本地);第二次来,你开口的第一句话就直接带着正事(HTTP 请求),连同会员卡一起奉上——对方验卡、解密、处理请求,一气呵成。握手时间:零。你敲下网址到发出真实请求之间,一个来回都不用等。
对天天访问的网站(搜索引擎、社交 App、视频网站——你的手机 90% 的流量都给了那几个熟面孔),0-RTT 的收益是实打实的:每次冷启动访问都省下一个 RTT。弱网高延迟场景(电梯、地库、偏远基站)里,一个 RTT 可能就是几百毫秒,省下来就是肉眼可见的"秒开"。但这一招有代价,而且代价不小——下一节专门算这笔安全账。
天下没有免费的快:0-RTT 与重放攻击
0-RTT 的麻烦出在一个根本性的区别上:会员卡是"昨天"发的,可你今天进门说的第一句话,坏人可能"录了音"。攻击场景推演一遍:你在咖啡馆连了不可信的 WiFi,用 0-RTT 发出一个请求(比如"给这个帖子点赞");隔壁桌的坏人把这个加密请求原样复制一份,过五分钟原样再发给服务器一遍、十遍地发。服务器会怎么想?在它看来,这些都是"持有合法会员卡的人发来的合法加密请求"——卡是真的,加密是真的,它没有任何理由拒绝。这就是"重放攻击"(replay):坏人不需要破解加密,只需要把你的原话重播。
解决办法是行业级的谨慎:0-RTT 里只允许携带"做一次和做十次结果一样"的请求——这类操作术语叫"幂等"。查首页、拉新闻流、看图片地址,重播一万次也无害(结果都一样);但下单、转账、改密码这类"做十次会出事"的操作,一律禁止走 0-RTT 快车道,必须退回一 RTT 的完整握手——多等一个来回,换一个"重播无效"的保证。这背后是一个值得记住的工程哲学:快与安全经常是一对掰手腕的兄弟,成熟协议的做法不是选边站,而是划车道——安全的车道快跑,危险的车道慢行。你平时用 App 感受不到这一切,是因为浏览器和服务器替你把车道划分好了。
连接迁移:把身份从地址上剥下来
现在讲第二招绝活——上一节埋的伏笔正式揭晓。先看老协议怎么认人:TCP 判断"这是同一条连接"的依据是四元组——你的 IP、你的端口、对方的 IP、对方的端口,四个数字全对上才算同一条连接。这套逻辑在 1981 年天衣无缝:一台电脑一个 IP,IP 就是身份,身份就是地址,三者合一。问题是 2020 年代的移动互联网把这整套假设砸了——你的 IP 一天要变好几次:出家门 WiFi 切 5G,进电梯 5G 切 4G,到了公司又切公司 WiFi。四元组里你的 IP 一变,四缺一,TCP 立刻翻脸不认人:旧连接宣告死亡,一切重来。
QUIC 的解法是给连接发一张与地址无关的会员卡:Connection ID(连接标识符)。建立连接时双方各发一张卡号,之后所有数据包上都盖着这个卡号。你从 WiFi 搬到 5G,IP 换了、端口可能也换了,但包上的卡号原封不动——服务器一看卡号:"老熟人,地址变了而已,接着聊。"连接不散、加密不重谈、下载进度不丢,正在播的视频连一帧都不卡。本质上就是把"身份"从"地址"这个易变属性上解耦出来,绑到一个双方约定的稳定编号上。这招在计算机网络史上并不新鲜——你的手机号就是同样的设计:人可以换城市、换手机、换运营商,号码不变,朋友照样找得到你。QUIC 只是把这个三十年的社会经验用在了传输层。
细节上 QUIC 还做了一步"防冒领":你换了新地址后,服务器会先在新地址上发一个小小的试探(相当于"请报卡号后四位"),你答对了,它才放心地在新疆道上全速发数据——防止坏人谎报别人的卡号把数据引到自己家。术语叫"路径验证",你记住这个画面就够:会员卡虽然认人,换地址时还得对口令,双重保险。
你的生活里,迁移每天都在发生
连接迁移听起来是个工程师才会关心的特性?恰恰相反——它改变的是每个普通人每天几十次的切网体验。数一你的日常:地铁进站 WiFi 断了切蜂窝、视频会议从办公室走到会议室、打车 App 在地库里从 5G 掉到 3G、手机省电模式自动关 WiFi……每一次网络切换,老协议的剧本都是"断、重连、白屏一下",只是多数 App 用缓存和重试机制把这些尴尬遮住了,你以为是"信号抖了一下",其实是连接整个死过一次又复活了。
QUIC 的剧本则安静得多:卡号不变,接着传。视频通话不断人、游戏不掉线、长语音不中断。对需要长连接的场景(实时音视频、在线协作、即时通讯),这个特性几乎是为移动互联网量身定做的——这也是为什么各大视频会议和社交 App 是 QUIC 最积极的早期采用者。想象一下在线考试或者直播带货的场景:主播从直播间走到走廊,网络从 WiFi 切到 5G,直播一秒不断——观众根本不知道主播刚刚"搬了家"。好的底层技术就该这样:你感觉不到它,只感觉到"怎么今天这么稳"。
顺手升级:包号与回执也换了新规矩
除了两招绝活,QUIC 还把 TCP 两套用了四十年的老规矩顺手翻新了——概念上值得认识一下,因为它们解释了"为什么 QUIC 能在丢包多发的无线网络上表现更好"。
第一套是包编号。TCP 给每个字节编的序号有个历史包袱:序号按"数据的第一个字节在整个流里的位置"编号,包丢了重传时,重传的包用的是原来的序号——收发双方得靠猜来分辨"这是新数据还是重传的老数据"。QUIC 改成给每个包编单调递增的发送序号:第一发是 7 号,重传就是 8 号(哪怕装的是同样的内容),9 号、10 号……永远往前走。好处是接收方一秒钟就能算出"这包是第几次发的、路上花了多久、丢了几个",重传判断从"推理题"变成了"看编号"。相当于快递单号:老规矩是"按货品在仓库里的货架号贴单"(重发的货还是那个货架号,你得查记录才知道是不是补发),新规矩是"每一票都盖新的流水号"——丢了补发,补发也有自己的号,一目了然。
第二套是回执(确认机制)。TCP 早期的回执只有一句话:"我收到了 1 到 100 号。"中间丢一个包,得靠后来打补丁的扩展(选择性确认)才能表达"收 1-50 和 60-100,中间 51-59 没到"。QUIC 从设计图上就把回执做成了一张明细清单:收到了哪些区间、最小的没收到是几号、新数据等了多久——一次说清。发方拿到这张清单,重传什么、该不该加速、网络堵不堵,判断起来又快又准。两套新规矩合起来,让 QUIC 在同样的烂网络上传得更稳——这也是下一节之后讲拥塞控制(§ 10.5 BBR)时"判断路况"的数据底座。顺带预告 § 10.5 的一个关键设定:QUIC 把拥塞控制做成了可插拔的模块——协议只规定接口,具体算法随便换,就像发动机舱统一了接口,换引擎不用重造整车。这个设计后来被证明极具前瞻性:新算法在 QUIC 上的试验和铺开速度,远快于在 TCP 上的同类尝试——又一次,"搬进用户态"的红利。
温故知新:为什么必须是 UDP 的壳
上一节讲过 QUIC 选 UDP 当地基的三层理由(UDP 没被设备动过手脚、用户态部署快、从零设计无包袱),这里换一个角度把这件事钉牢——假设不这么干会怎样?如果当年 Google 选择"改造 TCP":加个字段支持连接迁移、加个选项合并加密握手。第一关就过不去:全球几十亿台设备里的 TCP 实现烧死在固件和旧系统里,新字段路过老路由器,十有八九被当成"不认识的脏东西"丢弃或剥掉——你的改良只对全新设备生效,而新旧设备得混用十几年,改良等于没改。这不是猜测,是 TCP 历史上真实发生过多次的失败模式(协议僵化的实证案例能列出长长一串)。
反观 UDP 这条路:UDP 报文对中间设备来说就是"一坨不透明的数据",没人检查、没人修改、没人丢弃——正因为 UDP 简单到不值一改,它成了唯一没被冻结的传输层通道。QUIC 把自己整套新规矩塞进 UDP 的壳里,像特种部队借了辆民牌车:路况(互联网设备)对它一视同仁,车上装什么(新协议)沿途没人管。这套"借壳创新"的思路后来被反复效仿——下一节的加密 DNS(DoH)走的是完全相同的路线:新协议躲进老协议的壳里,绕开互联网的"免疫系统"。看懂这一个模式,你看现代协议演进的眼光就换了一档:先问"路能不能过",再问"车造得好不好"。
换网故事的另一半:NAT 这个隐形房管
讲到"换网断线",还有一个隐形角色必须揪出来——NAT(网络地址转换)。它就是术语表里"一栋楼共用一个总机"的那位:你家路由器把全家设备的流量统一翻译成同一个公网 IP 发出去,回来再按端口号分发回各设备。IPv4 地址不够用的年代(下一节的主菜),NAT 是全人类赖以续命的土办法——但它在 TCP 的换网故事里,还扮演着一个少有人知的反派。
NAT 的总机有一个毛病:电话簿有保质期。路由器为你的每条连接记一条翻译规则("家里设备的 55666 端口 ↔ 公网 IP 的 40001 端口 ↔ 对方服务器"),但这条规则不是永久的——空闲太久(常见几分钟到几十分钟),路由器就把这页电话簿撕了,把端口号回收给别人用。于是经常出现这种冤案:你的 IP 没换、WiFi 没掉、连接的 TCP 四元组分毫未动——但 NAT 总机那页记录过期了,回信再也翻译不回你桌上。TCP 的世界里,这条连接成了一条"双方都以为活着、实际已被掐断"的幽灵连接,只能等超时才发现。这就是为什么即时通讯 App 要定时发"心跳包"——不是为了浪漫,是为了让 NAT 总机别撕掉自己那页电话簿。
QUIC 对 NAT 的态度也优雅得多:会员卡在,连接就在——哪怕 NAT 换了端口、撕了旧页、重发了新号,包上的 Connection ID 依然认得出来路,路径验证对口令一过,接着走。说白了,TCP 的连接健康要仰仗链条上每一环都完好(自家 NAT、运营商 NAT、双方 IP),QUIC 只需要双方还记得卡号。链路上随便哪环塌了,重新拨通就续上——这又是"身份与地址解耦"红利的延伸:解耦不只是抗换网,还抗"中间人失忆"。
一个冷知识:QUIC 的连接,操作系统看不见
学过 § 9.5 的同学请做个思想实验:在跑着 QUIC 的电脑上敲 netstat,能看到这条 QUIC 连接吗?答案是:看不到——至少看不到你以为的那种"连接"。你能看到的只是一个 UDP 套接字(ss -u 那张表里的一行),没有 ESTABLISHED 状态、没有对端地址、没有收发队列。因为在操作系统眼里,UDP 没有"连接"这个概念(§ 3.3 的老设定:放下就走),QUIC 的握手、卡号、流、加密,全部发生在应用软件自己的内存里——操作系统只是个帮忙收发包裹的邮差,包裹里装的是什么组织架构,它一无所知。
这个小实验藏着本节反复出现的那条分界线的实体版:TCP 的连接是操作系统内核里的数据结构(所以 netstat 列得出它、所以升级 TCP 得换内核);QUIC 的连接是应用进程里的数据结构(所以 netstat 看不见它、所以浏览器更新一版 QUIC 就跟着升级)。一表之内,两个世界——你现在有了亲眼看穿它的能力:netstat 里查无此人、udp 443 却流量汹涌,八成就是 QUIC 在跑。这也是排错视角的实弹:§ 9.5 的"四层门"排查法遇到 QUIC App 时,"门开了没"这一问要看 UDP 套接字,别再等一个永远不会出现的 LISTENING。
迁移的边界:它不是"永不断线"的魔法
夸了这么久连接迁移,按规矩泼三瓢冷水——它有边界,而且边界都是现实世界画的:
- 边界一:对方得会说 QUIC会员卡得两边都认。服务器没开 QUIC、或中间网络把 UDP 443 掐了(少数校园网、企业网至今对 UDP 不友好),连接立刻退回 TCP——退路机制是每个成熟 QUIC 实现的标配,"能 QUIC 就 QUIC,不行马上 TCP"。
- 边界二:切网瞬间的空窗换网再无缝,新路径也要重新验证(对口令那一步),几十毫秒的空窗内包仍在走老路、自然全部丢失——只是连接不死、恢复极快。体感上是"卡了半拍",不是"断了重连"。
- 边界三:App 得正确实现协议给了不断线的能力,App 若在网络切换回调里自己把连接扔了重建(实现偷懒的老代码),神仙协议也救不了。你偶尔遇到"明明是新版协议还断"的情况,锅多半在应用层。
至于未来——迁移的下一代已经在路上:多路径 QUIC(Multipath QUIC)。今天"WiFi 和 5G 只能二选一、切换时无缝",明天的目标是两条路同时走:视频会议的流量同时从 WiFi 和 5G 双路上传输,哪条快走哪条、哪条断了另一条顶上,带宽还能叠加。这套思路在 TCP 世界有过先行者(MPTCP,苹果的语音助手当年用过它),但受制于内核升级难,始终小众;QUIC 把连接搬进用户态之后,多路径的实验和部署一下子轻快起来——正如本节一路的规律:身份解耦释放的想象力,远不止当初设计时想到的那些。
现实世界:谁在用 QUIC
这项技术离你有多近?把 2026 年的现实版图摊开看:
- 浏览器与网站:上一节验证过——主流大站相当比例已默认跑 HTTP/3(QUIC),你今天刷的视频网站、搜索引擎,很可能已经在用;
- 社交与视频 App:全球头部社交与短视频平台的 App 流量里,QUIC 占比已达大头——正是连接迁移和 0-RTT 对"移动+弱网"场景的价值,让它们成为最积极的推动者;
- 视频会议:实时音视频是长连接+切网频繁的重灾区,QUIC 的迁移特性在这里几乎是刚需;
- 边缘网络与 CDN:各大云厂商的边缘节点全面支持 HTTP/3,等于替千百万中小网站一键开启;
- 国内视角:主流国内 App 与视频平台同样在跟进——QUIC 的"移动+弱网"红利对国内复杂的网络环境(高铁、地铁、人流密集商圈)尤其对口,头部大厂多有自研或深度定制的 QUIC 实现,开源社区也有成熟的国产实现可用;
- 更远的涟漪:连 DNS 都有了 QUIC 版本(DoQ,§ 10.4 见),新一代代理与"企业 VPN"技术也在把 QUIC 当底座——凡是"移动、弱网、长连接"三占其二的地方,都有它的身影。
一句话总结版图——简单说:QUIC 已经过了"要不要用"的争论期,进入了"哪里还没用上"的铺开期。推动它的不是协议委员会的热情,而是移动用户的体验账——每一次切网不断线、每一次秒开,都在替这项技术投票。
一段插曲:从私有实验到国际标准的一刀两断
本节讲的 QUIC,身世里还有一段值得单独讲的插曲——它是理解"标准化"这件事的活教材。你如今见到的 QUIC,和 Google 2012 年最初部署的 QUIC,名字相同,血缘相近,但互不兼容——两种方言,说的是两种话。
时间线是这样的:Google 在 Chrome 和自家服务之间先跑了多年私有版 QUIC(圈内称 gQUIC),验证了方向可行;2016 年起把它交给 IETF 开放标准化(§ 10.1 讲过那套吵出来的流程)。然后发生了一件很多工程团队不敢做的事:IETF 工作组评审过程中大刀阔斧地重设计——握手结构重写了、加密集成方式重做了、包格式重新定义了,最终 2021 年定稿的"国际版 QUIC"(iQUIC)与 Google 的私有版本完全不兼容:一台只说新方言的服务器,听不懂只会旧方言的客户端。Google 自己的迁移姿势也干脆利落——服务器宣布一个终止日期,旧方言下线,全球 Chrome 早已更新完毕,绝大多数用户从始至终不知道这场换代发生过。
这段插曲教给普通读者的东西,比技术本身更通用:原型用来说服世界,标准用来统一世界,两者职责不同,不必强行兼容。如果 IETF 为了兼容私有版而束手束脚,QUIC 会背着实验期的妥协包袱跑三十年;敢于一刀两断,是因为它当时还年轻、用户量还小——改造城市的时机永远在楼还没盖满的时候。你以后再看到任何"某某公司的私有协议宣布开放标准化",就知道该期待什么了:留下的会是思想,重写的会是细节。
诚实的账单:QUIC 的代价
讲到这儿全是优点,按本站的规矩,必须把账单也摊开——QUIC 不白快,它把成本转嫁到了别处:
- 代价一:CPU 更累TCP 的重活在操作系统内核里干了四十年,被优化到飞快;QUIC 跑在用户态(应用软件的地盘),加密、排包、确认样样要用通用代码现算——早期实现比 TCP 多花两三倍的 CPU。经过几年优化差距已大幅缩小,但"内核四十年的功力"仍是 TCP 的主场优势。
- 代价二:手机更费电CPU 多干活,电池就多耗。对每天刷八小时手机的普通人,这是几百万台设备加起来不小的一笔能耗;所以工程师才拼命优化 QUIC 实现,把这笔电费往回省。
- 代价三:UDP 路况参差有些运营商网络对 UDP 流量限速或区别对待(历史上 UDP 常被滥用,部分网络对它"另眼相看"),个别环境下 QUIC 反而跑不过 TCP——成熟的实现会自动探测、随时退回 TCP,两条腿走路。
- 代价四:调试更难全加密让中间设备什么都看不见——这对隐私是好事(§ 8 章的价值观),对排错是坏事:§ 9.6 的 Wireshark 只能看到 QUIC 的信封(卡号、包号),信纸全糊。工程师的调试工具被迫升级换代。
看到没,这份账单本身又是一堂课:工程里没有免费的午餐,只有把账从一张卡片挪到另一张卡片。QUIC 把"用户的等待"(延迟)挪成了"机器的辛劳"(CPU)和"运维的门槛"(调试难)。这笔交换划不划算?市场已经用脚投票:对面向亿万用户的产品,等待是每个人都付的税,CPU 是可以摊薄的成本——划算。但对一台内部小服务器、几万个固定客户端的内网系统,TCP 依然又稳又省——也划算。技术选型的真相从来不是"新的取代旧的",而是"各管各的最优场景"。
一张对照表:TCP 对 QUIC,逐项过堂
把这场"换代"收进一张表——左列是 TCP 的四十年,右列是 QUIC 的新方案:
| 维度 | TCP(1981) | QUIC(2021 定稿) |
|---|---|---|
| 连接身份 | 四元组(双方 IP+端口) | Connection ID,与地址解耦 |
| 换网表现 | 连接死亡,重头再来 | 无缝迁移,卡号认人 |
| 首访握手 | TCP 一个 RTT + TLS 一个起 | 合并握手,一个 RTT |
| 回访握手 | 至少一个 RTT | 0-RTT,开口就带正事 |
| 加密 | 外挂 TLS,两张皮 | 内置 TLS 1.3,一体设计 |
| 队头阻塞 | 整条连接一体株连 | 流间独立(上一节主讲) |
| 包编号 | 按字节位置,重传沿用旧号 | 单调递增,重传即新号 |
| 回执 | 一句话,扩展打补丁 | 明细清单,天生详尽 |
| 实现位置 | 操作系统内核 | 用户态(应用软件里) |
| 升级难度 | 等全球设备换代 | App 更新即升级 |
| 运行成本 | 低(内核四十年优化) | 较高(CPU、电池税) |
| 调试难度 | 中间可见,排错容易 | 全加密,工具换代 |
读这张表的方式:别找"谁更好",找"各自为什么长这样"。TCP 的每一项"落后"都拴着它的年龄——四元组是 1981 年"一台机器一个 IP"世界的合理设计;外挂 TLS 是"安全是后来才重要的事"的历史顺序;内核实现是"只有操作系统管得了全网"的时代逻辑。QUIC 的每一项"先进"也都拴着它的年龄——移动互联网、全民加密、App 快速迭代,都是 2010 年代才成型的世界。两份答卷都是各自时代的优等生,换代不是打脸,是时代换了考题。
老门店(TCP)的规矩:不办卡,认脸+登记住址。你每次进门,前台核对"脸、住址、门牌"——搬家了?对不起,系统里查无此人,重新排队登记、重新买手环(重新握手)。店越大规矩越多:进门登记一次(TCP 握手),再办个储物柜又登记一次(TLS 握手),第一次来的人光是进门就要折腾三轮。
新门店(QUIC)的规矩:进门只办一件事——发会员卡(合并握手),卡里直接写好储物柜密码(加密同步成立)。老会员更爽:刷脸直接进(0-RTT),手环都没停稳人已经在跑步机上了。你搬家、出差、换城市(换网络换 IP),卡照刷——系统认卡不认地址,跑步机上的训练计划一分不少地接着来(连接迁移)。当然,新店也有小心思:刷脸进门只能干"看看操课表"这种重播无害的事(幂等请求才许 0-RTT),要"办退卡"这种大事?请走人工窗口重新核对(完整握手)——不是不信任你,是防着你背后有人举着录音机。
新店的账单也诚实:智能化系统全靠店员手动跑(用户态实现,CPU 税),电费高一点、监控全加密(调试难)——但会员等的时间短了、换城市不断卡了,会员数就是最好的股东回报。
这张会员卡的故事就是 QUIC 的全部内核:认卡不认地址(Connection ID)、进门即办卡(合并握手)、老客刷脸(0-RTT)、大事走窗口(幂等保护)、账单转给电费(CPU 代价)。五个画面记牢,QUIC 你就算真懂了。
动手清单:亲眼见一见 QUIC
- F12 → 网络 → 协议列(上一节的功课),刷几个大站找
h3——那就是 QUIC 在跑; - 体验一次"协议协商":第一次访问是 h2、刷新后变 h3?你刚刚亲眼看到了 Alt-Svc 便条生效的全过程(先拿到便条,下次才说新话);
- 抓包侧:Wireshark 过滤器输
quic,看到 Initial 包里明文的版本协商、随后全加密的密文流——信封与信纸的边界一目了然; - 弱网实验(有条件的话):手机开热点、下载中途把 WiFi 关掉切蜂窝——跑 QUIC 的下载若能续传不断,你就亲身验收了连接迁移;
- 命令行:
curl -I --http3 某支持站点对比curl -I --http1.1 同站的耗时——亲眼见一见 0-RTT 省下的那一个 RTT。
常见误区
- 误区一:"QUIC 会取代 TCP,TCP 要死了"并存是常态,取代是童话。TCP 仍服务着互联网过半流量,内网、服务器间通信、老旧系统都活得很好。新技术铺开靠的是"新场景优先用",不是"老场景强制换"。
- 误区二:"0-RTT 万能,什么都能带上"恰恰相反:0-RTT 只对"重播无害"的幂等请求开放。下单、转账这类操作必须退回完整握手——快车道是有安全边界的,边界内的设计比快本身更重要。
- 误区三:"连接迁移 = WiFi 和 5G 同时下载加速"迁移解决的是"切换时不断线",不是"双网叠加提速"。它让切换无感,但一条连接同一时刻仍主要走一条路——多路径并发(MPTCP 的思路)是另一个话题。
- 误区四:"QUIC 比 TCP 快,因为 UDP 比 TCP 快"UDP 本身"快"只是因为没人管它——把可靠性全部自己实现的 QUIC,干的活不比 TCP 少。QUIC 快在握手合并、流独立、迁移这些设计,而不是 UDP 有什么魔法速度。
- 误区五:"Connection ID 泄露隐私,是个漏洞"设计上早有对策:卡号会定期更换(一轮新卡),且它本来就不含你的身份信息——它只是个双方约定的编号。真正的隐私增强恰恰是 QUIC 全加密带来的:连你看哪个域名,老协议裸奔的 SNI 都在被逐步加密(§ 10.4 的话题)。
带走三句话。第一,QUIC 的两招绝活同根同源:合并握手(首访一个 RTT、回访 0-RTT)与连接迁移(换网不断线),都源自同一次身份革命——把连接身份从"四元组地址"换成"Connection ID 会员卡"。第二,快是要付安全账的:0-RTT 对重放攻击天然脆弱,所以只有幂等请求准走快车道,下单转账必须回完整握手——车道划分比速度本身更能体现协议的成熟度。第三,账单诚实地记着:QUIC 把延迟税转成了 CPU 税和调试税,用户端体验变好、服务端成本变高——它赢在"亿万用户的等待更值钱"这道算术题上。
QUIC 用会员卡解决了"地址会变"的问题。但互联网还有一个更大的"地址危机"——四十年前设计的 32 位地址池早已见底,全世界靠"地址翻译"(NAT)硬撑到今天。下一代地址 IPv6 为什么推了三十年还没铺完?下一节:IPv6 全面部署——一场慢得离谱的全球搬迁。