HTTP1.0,HTTP1.1,HTTP2.0的主要特征对比

HTTP1.0css

是一种无状态、无链接的应用层协议。html

HTTP1.0规定浏览器和服务器保持短暂的链接,浏览器的每次请求都须要与服务器创建一个TCP链接,服务器处理完成后当即断开TCP链接(无链接),服务器不跟踪每一个客户端也不记录过去的请求(无状态)。算法

这种无状态性能够借助cookie/session机制来作身份认证和状态记录。而下面两个问题就比较麻烦了。segmentfault

首先,无链接的特性致使最大的性能缺陷就是没法复用链接。每次发送请求的时候,都须要进行一次TCP的链接,而TCP的链接释放过程又是比较费事的。这种无链接的特性会使得网络的利用率很是低。浏览器

其次就是队头阻塞(head of line blocking)。因为HTTP1.0规定下一个请求必须在前一个请求响应到达以前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,一样的后面的请求也给阻塞了。缓存

为了解决这些问题,HTTP1.1出现了。服务器

 

HTTP1.1cookie

对于HTTP1.1,不只继承了HTTP1.0简单的特色,还克服了诸多HTTP1.0性能上的问题。网络

首先是长链接HTTP1.1增长了一个Connection字段,经过设置Keep-Alive能够保持HTTP链接不断开,避免了每次客户端与服务器请求都要重复创建释放创建TCP链接,提升了网络的利用率。若是客户端想关闭HTTP链接,能够在请求头中携带Connection: false来告知服务器关闭请求。session

其次,是HTTP1.1支持请求管道化pipelining)。基于HTTP1.1的长链接,使得请求管线化成为可能。管线化使得请求可以“并行”传输。举个例子来讲,假如响应的主体是一个html页面,页面中包含了不少img,这个时候keep-alive就起了很大的做用,可以进行“并行”发送多个请求。(注意这里的“并行”并非真正意义上的并行传输,具体解释以下。)

须要注意的是,服务器必须按照客户端请求的前后顺序依次回送相应的结果,以保证客户端可以区分出每次请求的响应内容。

也就是说,HTTP管道化可让咱们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)。

如图所示,客户端同时发了两个请求分别来获取htmlcss,假如说服务器的css资源先准备就绪,服务器也会先发送html再发送css

换句话来讲,只有等到html响应的资源彻底传输完毕后,css响应的资源才能开始传输。也就是说,不容许同时存在两个并行的响应

 

可见,HTTP1.1仍是没法解决队头阻塞(head of line blocking)的问题。同时“管道化”技术存在各类各样的问题,因此不少浏览器要么根本不支持它,要么就直接默认关闭,而且开启的条件很苛刻...并且实际上好像并无什么用处。

那咱们在谷歌控制台看到的并行请求又是怎么一回事呢?

 

如图所示,绿色部分表明请求发起到服务器响应的一个等待时间,而蓝色部分表示资源的下载时间。按照理论来讲,HTTP响应理应当是前一个响应的资源下载完了,下一个响应的资源才能开始下载。而这里却出现了响应资源下载并行的状况。这又是为何呢?

其实,虽然HTTP1.1支持管道化,可是服务器也必须进行逐个响应的送回,这个是很大的一个缺陷。实际上,现阶段的浏览器厂商采起了另一种作法,它容许咱们打开多个TCP的会话。也就是说,上图咱们看到的并行,实际上是不一样的TCP链接上的HTTP请求和响应。这也就是咱们所熟悉的浏览器对同域下并行加载6~8个资源的限制。而这,才是真正的并行

此外,HTTP1.1还加入了缓存处理(强缓存和协商缓存[传送门])新的字段如cache-control,支持断点传输,以及增长了Host字段(使得一个服务器可以用来建立多个Web站点)。

 

 HTTP2.0

HTTP2.0的新特性大体以下:

二进制分帧

HTTP2.0经过在应用层和传输层之间增长一个二进制分帧层,突破了HTTP1.1的性能限制、改进传输性能。

可见,虽然HTTP2.0的协议和HTTP1.x协议之间的规范彻底不一样了,可是实际上HTTP2.0并无改变HTTP1.x的语义。
简单来讲,HTTP2.0只是把原来HTTP1.xheaderbody部分用frame从新封装了一层而已。

 

 多路复用(共享链接)

下面是几个概念:

  • 流(stream):已创建链接上的双向字节流。
  • 消息:与逻辑消息对应的完整的一系列数据帧。
  • 帧(frame):HTTP2.0通讯的最小单位,每一个帧包含帧头部,至少也会标识出当前帧所属的流(stream id)。

 

从图中可见,全部的HTTP2.0通讯都在一个TCP链接上完成,这个链接能够承载任意数量的双向数据流。

每一个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧能够乱序发送,而后再根据每一个帧头部的流标识符(stream id)从新组装。

举个例子,每一个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不一样属的帧能够在链接中随机混杂在一块儿。接收方能够根据stream id将帧再归属到各自不一样的请求当中去。

另外,多路复用(链接共享)可能会致使关键请求被阻塞。HTTP2.0里每一个数据流均可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还能够依赖其余的子数据流。

可见,HTTP2.0实现了真正的并行传输,它可以在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。

 

头部压缩

HTTP1.x中,头部元数据都是以纯文本的形式发送的,一般会给每一个请求增长500~800字节的负荷。

好比说cookie,默认状况下,浏览器会在每次请求的时候,把cookie附在header上面发送给服务器。(因为cookie比较大且每次都重复发送,通常不存储信息,只是用来作状态记录和身份认证)

HTTP2.0使用encoder来减小须要传输的header大小,通信双方各自cache一份header fields表,既避免了重复header的传输,又减少了须要传输的大小。高效的压缩算法能够很大的压缩header,减小发送包的数量从而下降延迟。

 

服务器推送

服务器除了对最初请求的响应外,服务器还能够额外的向客户端推送资源,而无需客户端明确的请求。

 

 HTTP1.1的合并请求是否适用于HTTP2.0

首先,答案是“没有必要”。之因此没有必要,是由于这跟HTTP2.0的头部压缩有很大的关系。

在头部压缩技术中,客户端和服务器均会维护两份相同的静态字典和动态字典。

在静态字典中,包含了常见的头部名称以及头部名称与值的组合。静态字典在首次请求时就可使用。那么如今头部的字段就能够被简写成静态字典中相应字段对应的index

而动态字典跟链接的上下文相关,每一个HTTP/2链接维护的动态字典是不尽相同的。动态字典能够在链接中不停的进行更新。

也就是说,本来完整的HTTP报文头部的键值对或字段,因为字典的存在,如今能够转换成索引index,在相应的端再进行查找还原,也就起到了压缩的做用。

因此,同一个链接上产生的请求和响应越多,动态字典累积得越全,头部压缩的效果也就越好,因此针对HTTP/2网站,最佳实践是不要合并资源。

另外,HTTP2.0多路复用使得请求能够并行传输,而HTTP1.1合并请求的一个缘由也是为了防止过多的HTTP请求带来的阻塞问题。而如今HTTP2.0已经可以并行传输了,因此合并请求也就没有必要了。

 

 

总结

HTTP1.0

  • 无状态、无链接

HTTP1.1

  • 持久链接
  • 请求管道化
  • 增长缓存处理(新的字段如cache-control
  • 增长Host字段、支持断点传输等

HTTP2.0

  • 二进制分帧
  • 多路复用(或链接共享)
  • 头部压缩
  • 服务器推送

 

转发自博客

https://segmentfault.com/a/1190000013028798