深度解读软件与工程generatedpublished

700个单词与三十年补丁:HTTP是如何靠权宜之计撑起整个互联网的

机制

1991年,万维网的发明人去美国德州开会,在酒店里向服务台借了一把电烙铁。 因为那家酒店根本没通网,而他从欧洲带来的调制解调器,连插头都对不上美国的插座。 他把机器外壳拆开,直接把电线焊进了酒店房间墙壁里的电话线接口。 他当晚要给同行演示的协议草案,全文只有 700 个英文单词。 那是他在欧洲核子研究中心给物理学家查论文随手写的。 规则只有一条:网页必须在十分之一秒内送达。 因为时间太紧,根本没有闲聊的余地。 浏览器建立连接,发过去一个单词 GET 和一个地址,服务器把纯文本吐出来,立刻挂断电话。 没有错误代码,没有身份验证,没有状态记录。 这就是 HTTP。 今天全世界每一个网页、每一个手机应用、每一个在深夜里疯狂爬取数据的 AI 模型,底下全跑着这套东西。

三十多年过去了,它几乎没有一样是按原计划跑下来的。 为了做网上购物车,工程师硬生生塞进去了 Cookie。 为了抢用户,所有浏览器都在报头里撒谎说自己叫 Mozilla。 甚至有一个拼写错误在里面躺了三十年,全世界没有任何一个工程师敢去把它改对。

那是 1995 年。 有人在邮件列表里问:你们有没有发现,HTTP 报头里的 Referer 好像少写了一个字母 r? 正确的英文是 Referrer,中间有两个 r。 参与讨论的罗伊·菲尔丁开玩笑说,要不把锅扣给法国人吧。 但玩笑归玩笑,当时跑在网上的服务器和解析脚本实在太多了。 只要有人把这个拼写改对,全球的网页追踪系统瞬间就会大面积瘫痪。 三十年后的今天,技术规范里依然保留着这行字:这是一个拼写错误,但大家必须继续这么错下去。

拼写错误顶多让人笑一笑,真正差点把互联网搞垮的是服务器那一头。 在早期的 HTTP 1.0 时代,你向服务器发请求,里面只有文件名,没有域名。 你访问一个网站,浏览器发出去的请求其实就一行:给我 index.html。 它根本没告诉服务器自己找的是哪个网站。 这意味着什么? 这意味着只要一台服务器连上网,它就只能放一个网站,必须独占一个独立的公网 IP 地址。 到了 1996 年,全世界的 IPv4 地址开始亮红灯。 总共只有 42 亿个地址,照这么挥霍,整个网络很快就会无地可用。 以太网的发明人罗伯特·梅特卡夫甚至在专栏里公开断言:互联网将在 1996 年发生灾难性崩溃。 怎么救? 工程师吉姆·盖蒂斯在邮件里叹着气写道:最优雅的做法本来是重写整个协议,但那会毁掉所有现存的服务器。 于是他们在 HTTP 1.1 里面打了一个极为实用的补丁。 每次发请求,必须附带一行报头:Host。 也就是在信封上明确写上,你敲开这扇大门,要找的到底是哪个域名。 就凭这简简单单的一行字,一台服务器就能同时托管成百上千个不同的网站。 今天几乎整个网络托管和云计算行业,都是从这行补丁里长出来的。 顺便说一下,到了 1997 年,互联网不仅没塌,梅特卡夫还在大会现场把自己的专栏文章撕碎泡在碗里,当着一千多人的面拿勺子吃了下去。

既然打补丁能应付,大家就开始得过且过。 从 1999 年 HTTP 1.1 正式定稿,接下来的 16 年里,整个互联网几乎没人敢动底层协议。 参与编写规范的工程师写下了一句大实话: 每一次推翻重来的尝试都失败了,因为现有的设计虽然一身毛病,但它好歹还能用,这就足以打消所有革命的念头。 既然底层不能动,工程师们就开始钻空子。 HTTP 1.1 规定,一个浏览器向同一台服务器最多只能同时开 2 条连接。 当年网页全是纯文本,2 条确实够用。 但后来网页塞满了图片和脚本,几十个文件排着队等这 2 条管道,页面卡得让人抓狂。 前端工程师怎么干的? 搞一堆假域名,把图片切到不同的子域名下面,强行骗过浏览器的连接数限制。 浏览器厂商也坐不住了。 2008 年微软发布 IE8,悄悄把连接上限改成了 6 条。 标准组织一看木已成舟,干脆在后来的规范里把 2 条连接这条禁令删得干干净净。

但大家都在拼命堆带宽,网页为什么还是慢? 2010 年,谷歌工程师迈克·贝尔什做了一组严密的网络测算,把底牌翻了出来: 把带宽翻一倍,网页加载速度只提升大约 5%。 但如果把往返延迟砍掉 20 毫秒,速度立刻提升 7% 到 15%。 瓶颈从来不在马路有多宽。 真正卡住速度的,是数据包在光纤里来回跑一趟要花多少时间。 谷歌没有等标准委员会慢吞吞地开会,直接在 Chrome 浏览器里做了一套新协议 SPDY。 它把多个请求压进同一条连接里并发传输,还能压缩报头。 这套方案后来被标准委员会采纳,变成了 HTTP/2。 结果新的矛盾又冒出来了。 开源缓存系统 Varnish 的作者普尔-亨宁·坎普直接公开嘲讽: 如果这是我班上学生交上来的协议设计作业,我会直接给不及格。 他的担忧很快被现实验证了。 HTTP/2 把所有请求塞进了一条单一的 TCP 管道。 而在 TCP 的设计里,数据包必须按严格的顺序组装。 只要中间丢了一个小包,整条连接就必须完全停下来等它重传,后面排队的所有网页资源全都跟着卡死在原地。 这就是队头阻塞。 网络顺畅时它飞快,一旦网络稍微有点波动,体验甚至不如老旧的 HTTP 1.1。

要绕开 TCP 的先天缺陷,唯一的办法是换掉它。 但全球的路由器、防火墙和操作系统内核,几十年来已经把 TCP 固化在硬件和系统里了。 想让全世界的机房同步升级网络协议栈,根本不可能办到。 谷歌工程师吉姆·罗斯金德想出了一个绝招:退回到无序的 UDP 协议。 UDP 传输不管顺序,只管丢数据包,剩下的重传和拥塞控制全部交给浏览器自己在应用层算。 这就是 QUIC,也是今天的 HTTP/3。 它绕过了僵化的操作系统,把网络传输的主导权直接拿回到了应用层。 今天全世界已经有超过五分之一的网页流量跑在它上面。

但每一次技术升级,往往也附赠了全新的漏洞。 HTTP/2 当年最自豪的一个功能,是允许浏览器随时单方面撤销请求。 结果到了 2023 年 8 月,黑客用这个机制发动了一场席卷全球的快速重置攻击。 攻击者一边疯狂建立请求,一边瞬间把它取消,每秒钟向目标轰出 3.98 亿次请求。 两分钟内的攻击流量,超过了维基百科整整一个月的全球总访问量。 谷歌、亚马逊和 Cloudflare 联合秘密排查了六个星期,才把这个窟窿补上。

而今天最新的战场,变成了满世界抓取数据的 AI 爬虫。 爬虫在抓取网页时,报头里的身份信息全是伪造的。 面对这群不守规矩的访客,网络防护巨头 Cloudflare 翻出了 1992 年蒂姆·伯纳斯-李随手写在备选清单里的一个古老状态码: HTTP 402。 它的定义是:需要付费。 这个状态码在技术文档里沉睡了三十多年,现在终于被推到了台前,用来拦截那些只想白嫖数据的机器人。

回过头看,1991 年在德州酒店里焊电线的那位发明人,其实从来没有得到他最初想要的万维网。 他当年设想的网际空间,每一个读者同时也是随手修改网页的作者。 但最终长成的世界,是那份 700 个单词的物理学小工具,被无数工程师、大厂和黑客一路修修补补,硬生生顶成了一座十万字规范的数字通天塔。 Cloudflare 现在每秒钟要处理超过 8000 万次 HTTP 请求。 这套支撑着整个人类文明运转的数字基石,地基从来不是什么深思熟虑的宏大工程。 剥开层层补丁,它里面依然跳动着当年那个最朴素的动作: 给我这份文档。 给你,拿好。 从来没有人真正把它做完过,大家只是边打补丁边往前狂奔。

引用 / CITATIONS

No citations exported.

同领域解读 / SOFTWARE & ENGINEERING

查看全部「软件与工程」解读 →

导出 / EXPORT

订阅 · SUBSCRIBE

每周一封独立、不受审查的科技与 AI 深度评论,周一发出。带出处,可核查。

不追踪邮件打开与邮件链接点击,一键退订。 或用 RSS · 详情