计网 http1.0/1.1/2.0 的区别

140 阅读4分钟

一、http1.0

  • http1.0 客户端与服务器只保持短暂的连接,每次请求都需要与服务器重新建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求

  • 比如在加载一个 html 文件时,当发现文件中存在其他资源文件的时候,这时候又创建单独的链接,最终导致,一个 html 文件的访问包含了多次的请求和响应,每次请求都需要创建连接、关系连接,这种形式明显造成了性能上的缺陷,如果需要建立长连接,需要设置一个非标准的Connection字段 Connection: keep-alive

二、http1.1

  • 在 http1.1 中,默认支持长连接(Connection: keep-alive),即在一个TCP连接上可以传送多个 http 请求和响应,减少了建立和关闭连接的消耗和延迟,比如在加载一个 html 文件时,文件中多个请求和响应就可以在一个连接中传输

  • http1.1 还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间

  • http1.1 增加了其他的请求方法,put、delete、options...

  • http1.1 增加更多的请求头和响应头来完善的功能

    1. 引入了更多的缓存控制策略,如If-Unmodified-Since, If-Match, If-None-Match等缓存头来控制缓存策略
    2. 引入range,允许值请求资源某个部分
    3. 引入host,实现了在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点

三、http2.0

由于 https 在安全方面已经做的非常好了,http 改进的关注点放在了性能方面。对于 http2.0 而言,它对于性能的提升主要在于两点:

  1. 头部压缩
  2. 多路复用

其他的亮点就是二进制分帧服务器推送

3-1 头部压缩

  • 在 http1.1 之前,请求体一般会有响应的压缩编码过程,通过Content-Encoding头部字段来指定,但是请求头并没有被压缩

当请求字段非常复杂的时候,尤其对于 GET 请求,请求报文几乎全是请求头,这个时候还是存在非常大的优化空间的。 http2.0 针对头部字段,也采用了对应的压缩算法——HPACK,对请求头进行压缩

HPACK 算法是专门为 http2.0 服务的,主要有两点:

  1. 首先是在服务器和客户端之间建立哈希表,将用到的字段存放在这张表中,那么在传输的时候对于之前出现过的值,只需要把索引(比如0,1,2,...)传给对方即可,对方拿到索引查表就行了。这种传索引的方式,可以说让请求头字段得到极大程度的精简和复用

image.png

  1. 对于整数和字符串进行哈夫曼编码,哈夫曼编码的原理就是先将所有出现的字符建立一张索引表,然后让出现次数多的字符对应的索引尽可能短,传输的时候也是传输这样的索引序列,可以达到非常高的压缩率

3-2 多路复用

http2.0 可以复用TCP连接,在一个连接里,客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序一一对应,这样就避免了”队头堵塞”

image.png

3-3 二进制分帧

  • http2.0 采用二进制格式传输数据,而非 http1 时候的文本格式,可以将请求和响应数据分割为更小的帧,并且它们采用二进制格式(01串),方便了机器的解析

  • Headers + Body的报文格式如今被拆分成了一个个二进制的帧,用Headers帧存放头部字段,Data帧存放请求体数据。分帧之后,服务器看到的不再是一个个完整的 HTTP 请求报文,而是一堆乱序的二进制帧。这些二进制帧不存在先后关系,因此也就不会排队等待,也就没有了 HTTP 的队头阻塞问题

  • 通信双方都可以给对方发送二进制帧,这种二进制帧的双向传输的序列,也叫做流(Stream)。http2.0 用流来在一个 TCP 连接上来进行多个数据帧的通信,这就是多路复用的概念

3-4 服务器推送

http2.0  的服务器推送(Server Push)。在 http2.0  当中,服务器已经不再是完全被动地接收请求,响应请求,它也能新建 stream 来给客户端发送消息,当 TCP 连接建立之后,比如浏览器请求一个 HTML 文件,服务器就可以在返回 HTML 的基础上,将 HTML 中引用到的其他资源文件一起返回给客户端,减少客户端的等待