HTTP/2.0的前世今生

前记

http协议是前端经常打交道的协议之一,发展至今已经到了2.0版本,这两天我刷完了《图解HTTP》,让我对与HTTP协议的发展史有了更深层的了解

万维网的出现和HTTP的诞生

时间要回到1989年的圣诞节,那一天李爵士发明了世界上第一个网页浏览器WorldWideWeb(同时也是网页编辑器)和第一个网页服务器。为了在网页浏览器和网页服务器中传输文本信息,李爵士将超文本嫁接到因特网上(超文本的概念并不是李爵士提出来的),由此诞生了超文本标记语言(HTML)

为了在万维网中发布和接收HTML,李爵士发明了超文本传输协议协议,也就是HTTP的诞生

最初的HTTP/0.9

1991年,李爵士发布文章标志着万维网公共项目的开始。在建立HTTP标准规范时,制定者主要想把HTTP当作传输HTML文档的协议,所以起初的协议非常简单。

请求由单行指令构成,以唯一可用方法GET开头,其后跟目标资源的路径(一旦连接到服务器,协议、服务器、端口号这些都不是必须的)。

GET /mypage.html

响应也极其简单的:只包含响应文档本身。

<HTML>这是一个非常简单的HTML页面</HTML>

跟后来的版本不同,HTTP/0.9的响应内容并不包含HTTP头,这意味着只有HTML文件可以传送,无法传输其他类型的文件;也没有状态码或错误代码:一旦出现问题,一个特殊的包含问题描述信息的HTML文件将被发回,供人们查看。

这时的HTTP协议,服务器发送完毕后就会关闭TCP连接

升级之后的HTTP/1.0

由于 HTTP/0.9 协议的应用十分有限,浏览器和服务器的迅速发展和扩展,使其已经不能够满足需要,所以,1996年5月,HTTP协议的1.0版本发布,这次发布的内容并没有被纳入标准,而是为1.1版本的构建可扩展性的尝试,更新的内容也非常多,主要有

  • 协议版本信息现在会随着每个请求发送(HTTP/1.0被追加到了GET行)
  • 状态码会在响应开始时发送,使浏览器能了解请求执行成功或失败,并相应调整行为(如更新或使用本地缓存)
  • 引入了HTTP头的概念,无论是对于请求还是响应,允许传输元数据,使协议变得非常灵活,更具扩展性
  • 在新HTTP头的帮助下,具备了传输除纯文本HTML文件以外其他类型文档的能力(感谢Content-Type头)

此时,HTTP的请求已经变成这样了

GET / HTTP/1.0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5)
Accept: */*
复制代码

响应变成了这样

HTTP/1.0 200 OK 
Content-Type: text/plain
Content-Length: 137582
Expires: Thu, 05 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 5 August 1996 15:55:28 GMT
Server: Apache 0.84

<html>
  <body>Hello World</body>
</html>
复制代码

此时的HTTP协议已经初具雏形,和我们现在看到的非常像,这是第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用,但是它并不是没有问题的,它仍然存在着0.9版本的问题,就是TCP连接不可以复用,每次发送请求都需要建立TCP连接,新建成本高,还需要发送前的预热。所以HTTP/1.0性能较差,为了解决这个问题,有些浏览器在发送请求时,使用了一个非标准的Connection字段。

Connection: keep-alive
复制代码

服务器不关闭TCP连接,以便其他请求复用,同样回复

Connection: keep-alive
复制代码

一个可以复用的TCP连接就建立了,直到客户端或服务器主动关闭连接。但是,这不是标准字段,不同实现的行为可能不一致,因此不是根本的解决办法。

标准的诞生HTTP/1.1

就在HTTP/1.0发布的几个月后,HTTP/1.1就诞生了,这次版本它进一步完善了HTTP协议,哪怕到今天都是最流行的协议之一

HTTP/1.1 消除了大量歧义内容并引入了多项改进:

  • 连接可以复用,节省了多次打开TCP连接加载网页文档资源的时间。
  • 增加流水线操作,允许在第一个应答被完全发送之前就发送第二个请求,以降低通信延迟。
  • 支持响应分块。
  • 引入额外的缓存控制机制。
  • 引入内容协商机制,包括语言,编码,类型等,并允许客户端和服务器之间约定以最合适的内容进行交换。
  • 感谢Host头,能够使不同域名配置在同一个IP地址的服务器上。

已经发展到这个时候,那么协议完美了吗

事实上并没有,虽然可以复用TCP连接,并且可以在一个连接中同时发送多个HTTP请求,但是服务端的处理是按顺序的,这就造成一个请求阻塞了,那么后面的所有请求的响应都会阻塞,这称为"队头堵塞"(Head-of-line blocking)

解决方法一是减少请求数,二是同时多开持久连接。但一般浏览器最多同时建立六个TCP连接

消除HTTP瓶颈的SPDY

随着时代的发展,web的用途开始变得多种多样,比如在线购物网站、社交网络服务、企业或组织内部的各种管理工具,等等

虽然这些功能已经通过web应用和脚本程序实现,但在性能上未必最优,这是因为HTTP协议上的限制以及自身性能有限。

以下这些HTTP标准就会成为瓶颈

  • 一条连接上服务端只可以返回一个请求
  • 请求只能从客户端开始,客户端不可以接收除响应以外的指令
  • 请求/响应首部未经压缩就发送。首部信息越多延迟越大
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多
  • 可任意选择数据压缩格式。非强制压缩发送

HTTP的功能不足可以通过创建一套全新的协议来弥补,可是目前基于HTTP协议的web浏览器已经遍布全球,因此无法完全抛弃HTTP,有一些新协议的规则是基于HTTP的,并在此基础上添加了新的功能

Google在2010年发布了SPDY,其开发目标旨在解决HTTP的性能瓶颈,缩短Web页面的加载时间(50%)

SPDY没有完全改写HTTP协议,而是在应用层和传输层之间通过新加会话层的形式运作。同时,考虑到安全性问题,SPDY规定通信中使用SSL。

SPDY还是采用HTTP建立通信连接。因此还是可以使用HTTP的GET或POST等方法、Cookie以及HTTP报文等。

HTTP获得了以下额外的功能

  • 多路复用流
  • 赋予请求优先级
  • 压缩HTTP首部
  • 推送功能
  • 服务器提示功能

SPDY解决了部分问题,但是并没有从根本解决问题。

但这个协议在Chrome浏览器上证明可行以后,就被当作 HTTP/2 的基础,主要特性都在 HTTP/2 之中得到继承。

期盼的HTTP/2.0的诞生

HTTP/2.0的目标是改善用户在使用Web时的速度体验

对比HTTP/1.1,改善有如下几点

  • HTTP/2是二进制协议而不是文本协议。它不能再手动读取和创建,改善的优化技术现在可被实施。
  • 这是一个复用协议。并行的请求能在同一个链接中处理,移除了HTTP/1.x中顺序和阻塞的约束。
  • 头部压缩,因为headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
  • 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。

参考资料

阮一峰博客 MDN 《图解HTTP》

猜你喜欢

转载自juejin.im/post/5c8a018be51d4558a23454e7