HTTP1.1
随着互联网的快速发展,HTTP/1.0也无法满足用户需求了,最根本的问题就是连接问题。因为HTTP1.0是基于TCP设计的,所以HTTP/1.0 每进行一次通信,都需要经历 建立连接、传输数据和断开连接三个阶段。随着浏览器普及,单个页面中的图片文件越来越多,有时候一个页面可能包含了几百个外部引用的资源文件,如果在下载每个文件的时候,都需要经历建立TCP连接、传输数据和断开连接这样的步骤,无疑会增加大量无谓的开销。
为了解决 HTTP/1.0 的问题,1999 年推出的 HTTP/1.1 有以下特点:
1. 改进持久连接
HTTP/1.1 中增加了持久连接的方法,它的特点是在一个TCP连接上可以传输多个HTTP请求,只要浏览器或服务器没有明确断开连接,那么该TCP连接会一直保持。
HTTP的持久连接可以有效减少TCP建立连接和断开连接的次数,这样的好处是减少了服务器额外的负担,并提升整体HTTP的请求时间。
持久连接在HTTP/1.1 中是默认开启的,如果不想采用持久连接,可以在HTTP请求头中加上 Connection: close。目前浏览器中对于同一个域名,默认允许同时建立6个TCP持久连接。
2. 不成熟的HTTP管道化
持久连接虽然能减少TCP的建立和断开次数,但是它需要等待前面的请求返回之后,才能进行下一次请求。如果某个请求由于某些原因没有及时返回,那么就会阻塞后面的所有请求,这就是著名的队头阻塞问题。
请求管道化(pipelining)——尴尬的假并行传输,可以在同个连接发送多个请求,虽然可以整批发送请求,但服务器依然需要根据请求顺序来回复浏览器的请求,可能会发生阻塞(队头阻塞),最终被各大厂商放弃。
3. 提供虚拟主机的支持
在HTTP/1.0 中每个域名绑定了唯一的IP地址,因此一个服务器只能支持一个域名。但是随着虚拟主机技术的发展,需要实现在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个IP地址。
因此,HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的Host值做不同的处理。
4. 对动态生成的内容提供了完美支持
在HTTP/1.0时,需要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。
HTTP/1.1 通过引入 Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上 上个数据块的长度,最后使用一个零长度的块作为数据发送完成的标志,这样就提供了对动态内容的支持。
5.客户端Cookie
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,浏览器之后向同一服务器再次发起请求时会携带上该cookie,用于告知服务端两个请求是否来自同一浏览器。
// 响应头
Set-Cookie: yummy_cookie=choco
// 请求头
Cookie: yummy_cookie=choco;
HTTP1.1还加入了缓存处理(强缓存和协商缓存)新的字段如cache-control
总结
- 默认使用持久连接Connection: keep-alive
- 不成熟的HTTP请求管道化(pipelining)——尴尬的假并行传输,虽然能同时发起多个请求,但是得按顺序接收,也可能造成队头阻塞
- 增加
Host字段、支持断点传输等(把文件分成几部分) - 增加 PUT、DELETE、OPTIONS等方法
- HTTP1.1还加入了缓存处理(强缓存和协商缓存)新的字段如
cache-control
HTTP/1.1为网络效率做了大量的优化,最核心的有如下三种方式:
- 增加了持久连接;
- 浏览器为每个域名最多同时维护6个TCP持久连接;
- 使用CDN实现域名分片机制。
HTTP/1.1 的主要问题
HTTP/1.1对带宽的利用率却并不理想,这也是HTTP/1.1的一个核心问题。
之所以说HTTP/1.1对带宽的利用率不理想,是因为HTTP/1.1很难将带宽用满。比如我们常说的100M带宽, 实际的下载速度能达到12.5M/S,而采用HTTP/1.1时,也许在加载⻚面资源时最大只能使用到2.5M/S,很难将12.5M全部用满。主要有以下几个原因:
-
TCP的慢启动
一旦一个TCP连接建立之后,就进入了发送数据状态,刚开始TCP协议会采用一个非常慢的速度去发送数据,然后慢慢加快发送数据的速度,直到发送数据的速度达到一个理想状态,我们把这个过程称为
慢启动。而之所以说慢启动会带来性能问题,是因为页面中常用的一些关键资源文件本来就不大,如HTML文件、 CSS文件和JavaScript文件,通常这些文件在TCP连接建立好之后就要发起请求的,但这个过程是慢启动,所以耗费的时间比正常的时间要多很多,这样就推迟了宝贵的首次渲染页面的时间了。
-
TCP之间多个连接会互相竞争固定的带宽
-
HTTP/1.1 队头阻塞的问题:
在HTTP/1.1中使用持久连接时,虽然能公用一个TCP管道,但是在一个管道中同 一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。这意味着我们不能 随意在一个管道中发送请求和接收内容。
HTTP/1.1所存在的一些主要问题: 慢启动和TCP连接之间相互竞争带宽是由于TCP本身的机制导致的,而队头阻塞是由于HTTP/1.1的机制导致的。