http/0.9到http/2版本解读

本文参考自https://blog.poetries.top/browser-working-principle/guide/part6/lesson29.html

对http从http/0.9版本到当前广泛使用的http/2版本的发展历程进行了一个详细的介绍

HTTP/0.9

  • 因为HTTP是基于TCP协议的,所以客户端要先根据IP地址、端口号和服务器建立连接,而建立连接的过程就是TCP三次握手的过程
  • 建立好连接之后,会发送一个GET请求行的信息,比如GET index.html来请求index.html文件
  • 服务器接收请求信息之后,读取对应的HTML文件,并按照ASCII字节流的形式返回
  • HTML文件传输完成后,通过四次挥手断开连接

在这里插入图片描述

总的来说,当时的需求很简单,就是用来请求体积较小的html文件,因此HTTP/0.9有以下三个特点:
1、第一个就是只有一个请求行,并没有HTTP请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了
2、第二个是服务器端也没有返回头信息,这是因为服务器也不需要告诉客户端过多的信息,只需要返回数据就可以了
3、第三个是返回的文件内容是ASCII字符流进行传输的,因为都是HTML格式文件,所以使用ASCII字节码传输是最合适的

随着万维网的告诉发展,浏览器中展示的不单单是html文件了,对多种数据展示的需求成为了HTTP/1.0的一个核心诉求

HTTP/1.0

最大特点为引入了请求头和响应头,通过键值对的方式解决了多种类型文件传输的问题,除此之外,状态码的引入使客户端可以知道请求处理的结果,HTTP/1.0中引入了Cache机制,用来缓存已经下载过的数据,可以减轻服务器的压力,服务器通过用户代理的字段来统计客户端的基础信息

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

在这里插入图片描述

要支持多种类型的文件,我们就需要解决以下几个问题

  • 首先,浏览器需要知道服务器返回的数据是什么类型的,然后浏览器才能根据不同的数据类型做针对性的处理。(需知道返回的数据类型)
  • 其次,由于万维网所支持的应用变得越来越广,所以单个文件的数据量也变得越来越大。为了减轻传输性能,服务器会对数据进行压缩后再传输,所以浏览器需要知道服务器压缩的方法。(需知道服务器的压缩方法)
  • 再次,由于万维网是支持全球范围的,所以需要提供国际化的支持,服务器需要对不同的地区提供不同的语言版本,这就需要浏览器告诉服务器它想要什么语言版本的页面。(需告诉服务器想要的语言版本)
  • 最后,由于增加了各种不同类型的文件,而每种文件的编码形式又可能不一样,为了能够准确地读取文件,浏览器需要知道文件的编码类型(需知道文件的编码类型)

HTTP/1.0在浏览器发起请求时,在请求头中加入所要请求的文件类型、期待服务器的压缩格式、编码类型以及语言类型,服务器在收到请求头时,会分析该请求头中所传入的参数,并按照要求读取所需要的数据,并按照特定编码及压缩方式进行打包,若服务器不支持特定的打包方式,则会进行替换,完成打包后,服务器会为客户端返回一个请求头,请求头中包含返回数据的类型、编码方式、压缩方式和语言类型等信息,有了响应头的信息,浏览器就会使用 br 方法来解压文件,再按照 指定的编码格式来处理原始文件,最后按照文件类型标准来解析该文件。这就是 HTTP/1.0 支持多文件的一个基本的处理流程。

HTTP/1.1

改进持久的连接

即将先前的短连接改为长连接

HTTP/1.0每次请求都要经过建立TCP连接、传输HTTP数据、断开TCP连接三个阶段,随着浏览器的普及,页面频繁发起请求会造成TCP不停地连接和断开,为解决这一问题,HTTP/1.1中引入了持久的连接,即一个TCP连接断开直接可以进行多次HTTP请求,只要浏览器和服务器没有明确表示断开连接,那么TCP会一直保持连接,持久连接在HTTP/1.1中是默认开启的,可在请求头中加入connection: close来关闭

不成熟的HTTP管化线

为解决队头阻塞的问题,HTTP/1.1中试图通过管化线的方式来解决该问题,是指客户端将整批http请求发送给服务器端,虽然可以进行整批发送请求,但是服务器端依然需要按照顺序来处理客户端的请求

提供虚拟主机的支持

在1.0中,每个域名绑定一个唯一的IP地址,因此一个服务器只能支持一个域名,但是随着虚拟主机的发展需要实现在一台物理主机上绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个 IP 地址。

因此,HTTP/1.1 的请求头中增加了Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。

对动态生成的内容提供了完美支持

在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。

HTTP/1.1 通过引入Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。

客户端Cookie、安全机制

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

小结

在HTTP的发展史用,起初HTTP/0.9因为需求简单,所以客户端与服务器之间的通信也相对简单(在请求时仅采用简单的请求行的方式进行请求,并且服务器端也没必要向客户端返回过多的信息

由于万维网的快速崛起,带来了大量新的需求,其中最核心的一个就是需要支持多种类型的文件下载, 为此 HTTP/1.0 中引入了请求头和响应头。在支持多种类型文件下载的基础之上,HTTP/1.0 还提供了 Cache 机制、用户代理、状态码等一些基础信息

但随着技术和需求的发展,人们对文件传输的速度要求越来越高,故又基于 HTTP/1.0 推出了 HTTP/1.1,增加了持久连接方法来提升连接效率,同时还尝试使用管线化技术提升效率(不过由于各种原因,管线化技术最终被各大厂商放弃了)。除此之外,HTTP/1.1 还引入了 Cookie、虚拟主机的支持、对动态内容的支持等特性

虽然 HTTP/1.1 在 HTTP/1.0 的基础之上做了大量的优化,但是由于一些效率问题始终很难解决,所以最终还是被 HTTP/2 所取代,这就是我们下一篇文章要介绍的内容了

HTTP/2

可参考该链接(地址

虽然 HTTP/1.1 采取了很多优化资源加载速度的策略,也取得了一定的效果,但是 HTTP/1.1对带宽的利用率却并不理想,这也是 HTTP/1.1 的一个核心问题

之所以会出现这个问题,主要是以下三个原因导致的:
1、TCP的慢启动
2、同时开启了多条TCP连接,那么这些连接会竞争固定的带宽
3、HTTP/1.1队头阻塞的问题

HTTP/2的多路复用

对于HTTP/1.1造成的队头阻塞问题,HTTP/2 的解决方案可以总结为:一个域名只使用一个 TCP 长连接和消除队头阻塞问题

在这里插入图片描述

该图就是 HTTP/2 最核心、最重要且最具颠覆性的多路复用机制。从图中你会发现每个请求都有一个对应的 ID,如 stream1 表示 index.html 的请求,stream2 表示 foo.css 的请求。这样在浏览器端,就可以随时将请求发送给服务器了。

服务器端接收到这些请求后,会根据自己的喜好来决定优先返回哪些内容,比如服务器可能早就缓存好了 index.html 和 bar.js 的响应头信息,那么当接收到请求的时候就可以立即把 index.html 和 bar.js 的响应头信息返回给浏览器,然后再将 index.html 和 bar.js 的响应体数据返回给浏览器。之所以可以随意发送,是因为每份数据都有对应的 ID,浏览器接收到之后,会筛选出相同 ID 的内容,将其拼接为完整的 HTTP 响应数据。

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

多路复用的实现

参考下图

在这里插入图片描述

从图中可以看出,HTTP/2 添加了一个二进制分帧层,那我们就结合图来分析下 HTTP/2 的请求和接收过程。

  • 首先,浏览器准备好请求数据,包括了请求行、请求头等信息,如果是 POST 方法,那么还要有请求体。
  • 这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器。
  • 服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。
  • 然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。
  • 同样,二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。
  • 浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求

从上面的流程可以看出,通过引入二进制分帧层,就实现了 HTTP 的多路复用技术

HTTP/2其他特性

1、可以设置请求的优先级
HTTP/2 提供了请求优先级,可以在发送请求时,标上该请求的优先级,这样服务器接收到请求之后,会优先处理优先级高的请求

2、服务器推送
除了设置请求的优先级外,HTTP/2 还可以直接将数据提前推送到浏览器。你可以想象这样一个场景,当用户请求一个 HTML 页面之后,服务器知道该 HTML 页面会引用几个重要的 JavaScript 文件和 CSS 文件,那么在接收到 HTML 请求之后,附带将要使用的 CSS 文件和 JavaScript 文件一并发送给浏览器,这样当浏览器解析完 HTML 文件之后,就能直接拿到需要的 CSS 文件和 JavaScript 文件,这对首次打开页面的速度起到了至关重要的作用

3、头部压缩

无论是 HTTP/1.1 还是 HTTP/2,它们都有请求头和响应头,这是浏览器和服务器的通信语言。HTTP/2 对请求头和响应头进行了压缩,你可能觉得一个 HTTP 的头文件没有多大,压不压缩可能关系不大,但你这样想一下,在浏览器发送请求的时候,基本上都是发送 HTTP 请求头,很少有请求体的发送,通常情况下页面也有 100 个左右的资源,如果将这 100 个请求头的数据压缩为原来的 20%,那么传输效率肯定能得到大幅提升

HTTP/2的缺陷

1、TCP的队头阻塞:当出现数据丢包时,会造成TCP的队头阻塞,这样的话会大大影响数据的传输效率

2、TCP建立连接的延时:我们知道HTTP/1和HTTP/2都是使用TCP协议来传输的,而如果使用HTTPS的话,还需要使用TLS协议进行安全传输,而使用TLS也需要一个握手的过程,这样就需要有两个握手延迟过程

  • 在TCP建立连接时,需要进行三次握手才能建立连接,这样就会消耗1.5个RTT(网络延迟,1RTT即客户端向服务器端发送一个数据包的时间加上服务器端向客户端发送一个数据包的时间),也就是说,需要在消耗完1.5个RTT之后才能进行数据传输
  • 进行TLS连接,TSL建立连接所花的时间大致时需要1-2个RTT,会在HTTPS进行详细介绍

3、TCP连接僵化:即想要自由地更新内核中的TCP西医时非常困难的

4、QUIC协议

HTTP/3 中的 QUIC 协议集合了以下几点功能。

  • 实现了类似 TCP 的流量控制、传输可靠性的功能。虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性。
  • 集成了 TLS 加密功能。目前 QUIC 使用的是 TLS1.3,相较于早期版本 TLS1.3 有更多的优点,其中最重要的一点是减少了握手所花费的 RTT 个数。
  • 实现了 HTTP/2 中的多路复用功能。和 TCP 不同,QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流(如下图)。实现了数据流的单独传输,就解决了 TCP 中队头阻塞的问题。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值