介绍下 HTTP 的演化过程和优化?

1. HTTP/1.0 存在的问题

  • 队头阻塞问题:因为只有⼀个连接,所以如果有⼀个请求被阻塞,后续请求也会被阻塞。
  • 无法多路复用:只能按顺序传输⼀个请求和响应,无法同时传输多个请求和响应。
  • 每次请求需要新建连接:每次请求都需要新建连接,连接的建⽴和关闭过程会消耗时间。

2. HTTP/1.0 到 HTTP/1.1 的优化:

  • 持久连接:在 HTTP/1.0 中,每次请求都需要建⽴⼀个新的TCP连接,⽽在 HTTP/1.1 中,引⼊了持久连接(也称为复⽤连接),这样可以在⼀个TCP连接上发送多个HTTP请求和响应,减少了TCP连接的建立和关闭所需的时间和资源消耗。
  • **管线化 [1]**:在 HTTP/1.1 中,⽀持请求管线化,即客户端可以同时发送多个请求,在服务端处理完第⼀个请求之前不必等待其它请求的返回。这种⽅式虽然提⾼了性能,但由于各个请求之间存在依赖关系,当其中⼀个请求出错时,会导致后续请求都失败.
  • 缓存方面,在 http1.0 中主要使用 header 里的 If-Modified-Since、Expires 来做为缓存判断的标准,http1.1 则引入了更多的缓存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略。
  • 支持 Host 字段: http1.1 中新增了 host 字段,通过在请求头中添加 Host 字段来区分不同的主机。用来指定服务器的域名。http1.0 中认为每台服务器都绑定一个唯一的 IP 地址,因此,请求消息中的 URL 并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机,并且它们共享一个IP地址。因此有了 host 字段,这样就可以将请求发往到同一台服务器上的不同网站。
  • 支持断点续传 : HTTP1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。http1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
  • 新增 HTTP 方法 : http1.1 相对于 http1.0 还新增了很多请求方法,如 PUT、HEAD、OPTIONS 等。

什么是管线化(管道网络运输)?

管道(pipeline)网络传输是指:可以在同一个 TCP 连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间。但是服务器还是按照顺序回应请求。如果前面的回应特别慢,后面就会有许多请求排队等着。这称为队头堵塞。

3. HTTP/1.1 到 HTTP/2 的优化:

  • 二进制协议:HTTP/2 是一个二进制协议。在 HTTP/1.1 版中,报文的头信息必须是文本(ASCII 编码),数据体可以是文本,也可以是二进制。HTTP/2 则是一个彻底的二进制协议,头信息和数据体都是二进制,并且统称为”帧”,可以分为头信息帧和数据帧。 帧的概念是它实现多路复用的基础。
  • 数据流: HTTP/2 使用了数据流的概念,因为 HTTP/2 的数据包是不按顺序发送的,同一个连接里面连续的数据包,可能属于不同的请求。因此,必须要对数据包做标记,指出它属于哪个请求。HTTP/2 将每个请求或回应的所有数据包,称为一个数据流。每个数据流都有一个独一无二的编号。数据包发送时,都必须标记数据流 ID ,用来区分它属于哪个数据流。
  • 多路复用:HTTP/1.x 中⼀个 TCP 连接只能同时处理⼀个请求,而 HTTP/2 中⽀持多路复用,即同⼀个连接客户端和服务器都可以同时发送多个请求或回应,而且不用按照顺序一一发送, 这样就避免了”队头堵塞”[1] 的问题。
  • 头信息压缩: HTTP/2 实现了头信息压缩,由于 HTTP 1.1 协议不带状态,每次请求都必须附上所有信息。所以,请求的很多字段都是重复的,比如 Cookie 和 User Agent ,一模一样的内容,每次请求都必须附带,这会浪费很多带宽,也影响速度。HTTP/2 对这一点做了优化,引入了头信息压缩机制。一方面,头信息使用 gzip 或 compress 压缩后再发送;另一方面,客户端和服务器同时维护一张头信息表(首部表),所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就能提高速度了。
  • 服务器推送: HTTP/2 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。使用服务器推送提前给客户端推送必要的资源,这样就可以相对减少一些延迟时间。这里需要注意的是 http2 下服务器主动推送的是静态资源,和 WebSocket 以及使用 SSE 等方式向客户端发送即时数据的推送是不同的。

什么是队头堵塞?

队头阻塞是由 HTTP 基本的“请求 - 应答”模型所导致的。HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求是没有优先级的,只有入队的先后顺序,排在最前面的请求会被最优先处理。如果队首的请求因为处理的太慢耽误了时间,那么队列里后面的所有请求也不得不跟着一起等待,结果就是其他的请求承担了不应有的时间成本,造成了队头堵塞的现象。

页面有多张图片,HTTP是怎样的加载表现?

  • 在HTTP 1下,浏览器对一个域名下最大TCP连接数为6,所以会请求多次。可以用多域名部署解决。这样可以提高同时请求的数目,加快页面图片的获取速度。
  • 在HTTP 2下,可以一瞬间加载出来很多资源,因为,HTTP2支持多路复用,可以在一个TCP连接中发送多个HTTP请求。

HTTP2的头部压缩算法是怎样的?

HTTP2的头部压缩是HPACK算法。在客户端和服务器两端建立“字典”,用索引号表示重复的字符串,采用哈夫曼编码来压缩整数和字符串,可以达到50%~90%的高压缩率。具体来说 :

  • 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送;
  • 首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
  • 每个新的首部键值对要么被追加到当前表的末尾,要么替换表中之前的值。

4. HTTP/2 到 HTTP/3 的优化:

img

了解

HTTP/3基于UDP协议实现了类似于TCP的多路复用数据流、传输可靠性等功能,这套功能被称为QUIC协议。

  • 流量控制、传输可靠性功能QUICUDP的基础上增加了一层来保证数据传输可靠性,它提供了数据包重传、拥塞控制、以及其他一些TCP中的特性。
  • 集成**TLS**加密功能:目前QUIC使用TLS1.3,减少了握手所花费的RTT数。
  • 多路复用:同一物理连接上可以有多个独立的逻辑数据流,实现了数据流的单独传输,解决了TCP的队头阻塞问题。
  • 快速握手:由于基于UDP,可以实现使用0 ~ 1RTT来建立连接。

介绍下 HTTP 的演化过程和优化?
http://example.com/2023/10/20/HTTP演化/
作者
weirdo
发布于
2023年10月20日
更新于
2023年10月24日
许可协议