HTTP1/2/3的发展和区别

不同版本HTTP

本文是对极客时间里李兵老师讲的浏览器工作原理与实践的笔记记录和总结。

一. HTTP/0.9

1991年提出,主要用于学术交流。最早出现的HTTP/0.9需求很简单——用来在网络之前传递HTML超文本内容。

特点:

  • 只有一个请求行(例如:GET /index.html ,用来获取index.html),并没有HTTP 请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了。
  • 服务器也没有返回头信息,这是因为服务器端并不需要告诉客户端太多信息,只需要返回数据就可以了。
  • 返回的文件内容是以 ASCII 字符流来传输的,因为都是 HTML 格式的文件,所以使用 ASCII 字节码来传输是最合适的。

二. 被浏览器推动的HTTP/1.0

万维网的高速发展带来了更多的需求,在浏览器中展示的不再单单是HTML文件,还包括了JavaScript、CSS、图片、音频等不同类型文件。

因此支持多种类型的文件下载是 HTTP/1.0 的一个核心诉求,而且文件格式不仅仅局限于ASCII编码,还有很多其他类型编码的文件

1. 如何支持多种类型文件下载

HTTP/0.9在建立好连接后,只会发送类似GET /index.html的简单命令请求,并没有其他途径告诉服务器更多的信息,如文件编码、文件类型等。同样,服务器也只是返回了数据给浏览器,也没有其他途径告诉浏览器关于返回数据的更多信息。

为了客户端和服务器能交流更多的信息,HTTP/1.0 引入了请求头和响应头,他们都是以KEY-VALUE形式保存的。在 HTTP 发送请求时,会带上请求头信息,服务器返回数据时,会先返回响应头信息。

基于以上需求,HTTP/1.0 的方案是通过请求头和响应头来进行协商,在发起请求时候会通过 HTTP 请求头告诉服务器它期待服务器返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码。例如:

accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh

当然并不是所有HTTP请求头里的内容服务器端都可以支持,但响应头里也会说明对应的信息内容:

content-encoding: br
content-type: text/html; charset=UTF-8

特性:

  • 有的请求服务器可能无法处理,或者处理出错,这时候就需要告诉浏览器服务器最终处理该请求的情况,这就引入了状态码。状态码是通过响应行的方式来通知浏览器的。
  • 为了减轻服务器的压力,在 HTTP/1.0 中提供了Cache 机制,用来缓存已经下载过的数据。
  • 服务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了用户代理的字段。

三. 缝缝补补的 HTTP/1.1

1. 改进持久连接

HTTP/1.0 每进行一次 HTTP 通信,都需要经历建立 TCP 连接、传输 HTTP 数据和断开TCP 连接三个阶段。但随着页面的发展,每个页面的引用开始变多,请求次数也变多,如果每次请求文件都需要重新建立TCP连接,那么开销就太大了。

为了解决这个问题HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持

持久连接在 HTTP/1.1 中是默认开启的,所以你不需要专门为了持久连接去 HTTP 请求头设置信息,如果你不想要采用持久连接,可以在 HTTP 请求头中加上Connection: close。目前浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。

2. 不成熟的HTTP管线化

持久连接虽然可以减少TCP建立和释放的次数,但是他需要等待前面的请求返回之后,才能进行下一次请求。如果中间有一个请求因为某种原因没有返回请求,就会阻塞后面的请求发送。这就是著名的队头阻塞

HTTP/1.1 中的管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。

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、安全机制

HTTP/1.1 还引入了客户端 Cookie 机制和安全机制。

6. 影响HTTP/1.1效率的因素

首先HTTP/1.1做了哪些优化?

  • 增加了持久连接;
  • 浏览器为每个域名最多同时维护 6 个 TCP 持久连接;
  • 使用 CDN 的实现域名分片机制。

哪些因素限制了HTTP/1.1?(HTTP/1.1主要是对带宽的利用率不理想)

  • TCP慢启动。一旦一个 TCP 连接建立之后,就进入了发送数据状态,刚开始 TCP 协议会采用一个非常慢的速度去发送数据,然后慢慢加快发送数据的速度,直到发送数据的速度达到一个理想状态,我们把这个过程称为慢启动。
  • 同时开启了多条 TCP 连接,那么这些连接会竞争固定的带宽。
  • HTTP/1.1 队头阻塞的问题。

四. HTTP/2.0的多路复用

HTTP/1.1 所存在的一些主要问题:慢启动TCP 连接之间相互竞争带宽是由于 TCP 本身的机制导致的,而队头阻塞是由于 HTTP/1.1 的机制导致的。

那么如何解决以上问题呢?虽然 TCP 有问题,但是我们依然没有换掉 TCP 的能力,所以我们就要想办法去规避 TCP的慢启动和 TCP 连接之间的竞争问题。

  • HTTP/2 的思路就是一个域名只使用一个 TCP 长连接来传输数据,这样整个页面资源的下载过程只需要一次慢启动,同时也避免了多个 TCP 连接竞争带宽所带来的问题。
  • 对于队头阻塞问题,HTTP/2 需要实现资源的并行请求,也就是任何时候都可以将请求发送给服务器,而并不需要等待其他请求的完成,然后服务器也可以随时返回处理好的请求资源给浏览器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pjZjOsSE-1630746627101)(D:\沸点前端\浏览器\img\HTTP2多路复用.png)]

从图中你会发现每个请求都有一个对应的 ID,如 stream1 表示 index.html 的请求,stream2 表示 foo.css 的请求。这样在浏览器端,就可以随时将请求发送给服务器了。

服务器端接收到这些请求后,会根据自己的喜好来决定优先返回哪些内容。

HTTP/2 使用了多路复用技术,可以将请求分成一帧一帧的数据去传输,这样带来了一个额外的好处,就是当收到一个优先级高的请求时,比如接收到 JavaScript 或者 CSS 关键资源的请求,服务器可以暂停之前的请求来优先处理关键资源的请求。

多路复用机制的实现是通过添加了一个二进制分帧层来实现的:

  • 浏览器准备好请求数据,包括了请求行、请求头等信息,如果是 POST 方法,那么还要有请求体。
  • 这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器。
  • 服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。
  • 同样,二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。
  • 浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求。
HTTP/2.0 其他特性
  1. 可以设置请求优先级
  2. 服务器推送。HTTP/2 还可以直接将数据提前推送到浏览器。你可以想象这样一个场景,当用户请求一个 HTML 页面之后,服务器知道该 HTML 页面会引用几个重要的JavaScript 文件和 CSS 文件,那么在接收到 HTML 请求之后,附带将要使用的 CSS 文件和 JavaScript 文件一并发送给浏览器,这样当浏览器解析完 HTML 文件之后,就能直接拿到需要的 CSS 文件和 JavaScript 文件,这对首次打开页面的速度起到了至关重要的作用。
  3. 头部压缩。无论是 HTTP/1.1 还是 HTTP/2,它们都有请求头和响应头,这是浏览器和服务器的通信语言。HTTP/2 对请求头和响应头进行了压缩。
HTTP/2.0的缺陷
  • TCP的队头阻塞。虽然 HTTP/2 解决了应用层面的队头阻塞问题,不过HTTP/2.0 依然是基于TCP协议的,而TCP最初就是为了单链接而设计的。但是在数据传输过程中,如果有一个数据因网络故障或其他原因而丢包,那么整个TCP的连接就会处于暂停状态,需要等待丢失的数据包被重新传输过来。因此,在TCP传输过程中,由于单个数据包的丢失而造成的阻塞被称为TCP上的队头阻塞
  • TCP建立连接的延时。因为 HTTP/1 和 HTTP/2 都是使用TCP协议传输的,而如果使用HTTPS的话还需要使用TLS协议进行安全传输,而TLS也需要一个握手过程,这样就需要有两个握手延迟过程。因此在传输数据之前,我们需要花掉3 - 4个RTT,如果浏览器和服务器的物理距离较远,就会造成很大的延时。

五. HTTP/3.0

由于上述 HTTP/2 中涉及到的TCP的缺陷,而由于中间设备的僵化难以去大量更大设备中设置的协议规则,去通过更改TCP协议是很难优化上述缺点的。

因此我们在 HTTP/3.0 中引入了QUIC协议
在这里插入图片描述

可以看到QUIC协议集合了以下几点功能:

  • 实现了类似TCP的流量控制、传输可靠性的功能
  • 集成了TLS加密功能
  • 实现了 HTTP/2 中的多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。
  • 实现了快速握手的功能。由于 QUIC 是基于 UDP 的,所以 QUIC 可以实现使用 0-RTT 或者 1-RTT 来建立连接,这意味着 QUIC 可以用最快的速度来发送和接收数据,这样可以大大提升首次打开页面的速度。
HTTP/3.0 的挑战

第一,服务器和浏览器都没有对HTTP/3提供比较完整的支持

第二,部署HTTP/3存在很大问题。因为系统内核对UDP的优化远远没有达到TCP的优化程度。

第三,中间设备僵化问题。这些设备对UDP的优化程度远远低于TCP,据统计使用QUIC协议时,大约有 3% - 7% 的丢包率。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值