第 1 章 HTTP 进化史

第 1 章 HTTP 进化史

在 20 世纪 30 年代,美国 MIT 工程学院的电子工程师 Vannevar Bush 研究了人们生产的信息量和社会消化信息的能力之间的关系。在 1945 年发表于《大西洋月刊》的文章“As We May Think”中,他写道:

从专业角度来看,我们传播和查阅研究结果的方法已经过时,现在已经完全不能满足需要了。如果在写作和阅读学术著作上花费的总时间可以被量化分析,那么两者的比例恐怕非常惊人。

他设想了这样一个系统:聚合起来的知识存储在微缩胶卷上,可以极其方便快速地查阅。他进一步指出,这些信息应当有上下文关联性,就像人类大脑构建的知识链接那样。尽管他设想的 memex(扩展存储器)系统从未实现,其思想却影响了后来者。

如今人们所熟知的术语超文本于 1963 年左右被创造出来,于 1965 年首次出现在 Ted Nelson 发表的文章中。Nelson 是一位软件设计师,同时也极具前瞻眼光。他提出“超文本”一词的含义如下:

大量的书面材料或图像材料以复杂的方式相互联系,因此不便在纸介质上呈现或展示。其中可能包含内容摘要,或者内容分布的脉络图以及各部分的内在联系;也可能包含审阅过其中内容的学者所添加的注释、补充或脚注。1

1T. H. Nelson. “Complex information processing: a file structure for the complex, the changing and the indeterminate.” ACM '65 Proceedings of the 1965 20th national conference.

Nelson 想要建立“文档库”,让信息之间互相关联,永不删除,并且方便所有人获取。20 世纪 70 年代,基于 Bush 的思想,Nelson 在他的 Xanadu 项目中实现了一个超文本系统的原型。很遗憾,该项目没有完成,但为后来者提供了基础。

1989 年,HTTP的 Tim Berners-Lee 提出了一个新的系统 2,用以记录粒子加速器(指日后的大型强子对撞机)和 CERN 所做实验产生的信息。他采用了 Nelson 的两个概念:超文本,或者说“以一种无约束的方式联系起来的人类可读信息”;超媒体,表示“不限于文本”。在提案中,Tim 提出要搭建“通用系统”,它由服务器和众多机器上的浏览器组成。

2https://www.w3.org/History/1989/proposal.html

1.1 HTTP/0.9和HTTP/1.0

HTTP/0.9 是个相当简单的协议。它只有一个方法(GET),没有首部,其设计目标也无非是获取 HTML(也就是说没有图片,只有文本)。

经过随后几年的发展,HTTP 逐渐流行起来。截至 1995 年,世界上有超过 18 000 台服务器在 80 端口处理 HTTP 请求。此协议在 0.9 版本的基础之上有了长足的发展,并于 1996 年通过 RFC 19453 制定为 HTTP/1.0 规范。

3https://tools.ietf.org/html/rfc1945

1.0 版本为原有的轻量协议新增了大量内容。0.9 版本的规范大概有 1 页,1.0 版本则有 60 页。所以,你可以说它从玩具成长为了工具。它包含了一些我们如今非常熟悉的概念:

  • 首部
  • 响应码
  • 重定向
  • 错误
  • 条件请求
  • 内容编码(压缩)
  • 更多的请求方法

    ……

尽管相对于 0.9 版本来说,HTTP/1.0 是一个巨大的飞跃,但仍存在很多瑕疵,尤其是不能让多个请求共用一个连接,缺少强制的 Host 首部,并且缓存的选择也相当简陋。这三点影响了 Web 可扩展的方式,因此应该在这里强调一下。

1.2 HTTP/1.1

1.0 版本刚刚制定,1.1 版本就接踵而来。截至目前,1.1 版本的协议已经使用了 20 多年了。它修复了之前提到的 1.0 版本的大量问题。因为强制要求客户端提供 Host 首部,所以虚拟主机托管成为可能,也就是在一个 IP 上提供多个 Web 服务。当使用新的连接指令时, Web 服务器也不需要在每个响应之后关闭连接。这对于提升性能和效率而言意义重大,因为浏览器再也不用为每个请求重新发起 TCP 连接了。

添加的变更如下:

  • 缓存相关首部的扩展
  • OPTIONS 方法
  • Upgrade 首部
  • Range(范围)请求
  • 压缩和传输编码(transfer-encoding)
  • 管道化(pipelining)

 管道化这种特性允许客户端一次发送所有的请求。但是有些问题阻碍了管道化的普及,服务器仍然只能按顺序响应请求。具体来说,如果某个请求花了很长时间,那么队头阻塞(head of line blocking)会影响其他请求。另外,互联网上的服务器和代理常常没有实现管道化特性(这很糟糕),或者实现得有问题(这更糟糕)。

HTTP/1.1 要归功于 HTTP/1.0 的成功,以及该版本运行那几年所积累的经验。

HTTP/1.1 的RFC

互联网工程任务组(IETF)发布的由委员会创建的草案中的协议规范,叫作 RFC(Request for Comments,请求注解)。委员会对所有人开放,前提是你有时间和意愿参与。HTTP/1.1 最早在 RFC 2068 中定义,之后被 RFC 2616 取代,最终在 RFC 7230 到 RFC 7235 中增补和修订。

1.3 1.1版本之后

自 1999 年起,RFC 2616(HTTP/1.1 规范)定义了建立现代 Web 所依赖的标准。正式定稿之后,它就不再变化,也不再改进。然而,Web 和我们使用 Web 的方式一直在变,这种变化甚至超出了它的创造者的想象。普通商业网站的交互性和实用性,已经远远超出了当年互相联系的文档库的设想,并且从根本上改变了我们与世界交互的方式。虽然我们今天看到了协议的各种限制,但进化并没有因此停止。

我们能指出的最明显的变化是网页的构成。HTTP 档案库(HTTP Archives)最早的记录是 2010 年,尽管距今的时间相对较短,变化也足够让人震惊。HTTP 协议设计之初的考虑是单次请求获取单个对象,但如今,新加入的每种元素都增加了复杂度,也带来了压力。

1.4 SPDY

2009 年,Google 的工程师 Mike Belshe 和 Roberto Peon 提出了一种 HTTP 的替代方案: SPDY4(发音同 speedy)。SPDY 不是第一个希望替代 HTTP 的方案,但它是其中最重要的一个,因为它带来了显而易见的性能提升。在 SPDY 之前,人们普遍认为在商业应用中没有必要对 HTTP/1.1 做出突破性的、不兼容的改变。要兼容浏览器、服务器、网络代理和其他各种各样的中间件,代价极其高昂。

4http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft1

然而,SPDY 改变了这一切。它很快证明了人们想要更高效的协议,并且愿意改变。SPDY 为 HTTP/2 奠定了基础,并证明了其中一些关键特性的合理性,如多路复用、帧和首部压缩等。即使在互联网时代,SPDY 的发展也算“快”的——它很快被整合进了 Chrome 和 Firefox,并最终几乎被所有主流浏览器所采有。而且几乎在同一时间,服务器和网络代理也对 SPDY 提供了必要的支持。

1.5 HTTP/2

2012 年初,HTTP 工作组(IETF 工作组中负责 HTTP 规范的小组)启动了开发下一个 HTTP 版本的工作。其纲领的关键部分 5 阐述了工作组对新协议的一些期望。

5https://datatracker.ietf.org/wg/httpbis/charter/

HTTP/2.0 被寄予了如下期望:

  • 相比于使用 TCP 的 HTTP/1.1,最终用户可感知的多数延迟都有能够量化的显著改善;
  • 解决 HTTP 中的队头阻塞问题;
  • 并行的实现机制不依赖与服务器建立多个连接,从而提升 TCP 连接的利用率,特别是在拥塞控制方面;
  • 保留 HTTP/1.1 的语义,可以利用已有的文档资源(如上所述),包括(但不限于)HTTP 方法、状态码、URI 和首部字段;
  • 明确定义 HTTP/2.0 和 HTTP/1.x 交互的方法,特别是通过中介时的方法(双向);
  • 明确指出它们可以被合理使用的新的扩展点和策略。

工作组发出了征求建议书的通知,并最终决定使用 SPDY 作为 HTTP/2.0 的起点。最终,RFC 7540 在 2015 年 5 月 14 日发布了,HTTP/2 成为正式协议。

下面,本书来为你讲完这个故事。

目录