本文主要介绍的是 HTTP/1.1,咱们先来学习下 HTTP/1.1 的进化史,而后再介绍在进化过程当中所遇到的各类瓶颈,以及对应的解决方法。浏览器
HTTP/0.9 是于 1991 年提出的,主要用于学术交流,需求很简单——用来在网络之间传递
HTML 超文本
的内容,因此被称为超文本传输协议
。
HTTP/0.9 的实现有如下三个特色:安全
- 第一个是只有一个请求行,并无 HTTP 请求头和请求体,由于只须要一个请求行就能够完整表达客户端的需求了。
- 第二个是服务器也没有返回头信息,这是由于服务器端并不须要告诉客户端太多信息,只须要返回数据就能够了。
- 第三个是返回的文件内容是以 ASCII 字符流来传输的,由于都是 HTML 格式的文件,因此使用 ASCII 字节码来传输是最合适的。
变化是这个世界永恒不变的主旋律,1994 年末出现了拨号上网服务,同年网景又推出一款浏览器,今后万维网就不局限于学术交流了,而是进入了高速的发展阶段。 万维网的高速发展带来了不少新的需求,而 HTTP/0.9 已经不能适用新兴网络的发展,因此这时就须要一个新的协议来支撑新兴网络,这就是 HTTP/1.0 诞生的缘由。性能优化
新兴网络带来了新的需求:首先在浏览器中展现的不单是 HTML 文件了,还包括了 JavaScript、CSS、图片、音频、视频等不一样类型的文件。所以支持多种类型的文件下载是 HTTP/1.0 的一个核心诉求,并且文件格式不只仅局限于 ASCII 编码,还有不少其余类型编码的文件。服务器
为了让客户端和服务器能更深刻地交流,HTTP/1.0 引入了
请求头
和响应头
,它们都是觉得 Key-Value 形式保存的,在 HTTP 发送请求时,会带上请求头信息,服务器返回数据时,会先返回响应头信息。
HTTP/1.0 的方案是经过请求头和响应头来进行协商,在发起请求时候会经过 HTTP 请求头告诉服务器它期待服务器返回什么类型的文件、采起什么形式的压缩、提供什么语言的文件以及文件的具体编码。网络
技术继续发展、需求不断迭代更新,HTTP/1.0也不能知足需求了,HTTP/1.1又在HTTP/1.0上继续更新:性能
HTTP/1.1 中增长了持久链接的方法,它的特色是在一个 TCP 链接上能够传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开链接,那么该 TCP 链接会一直保持。 HTTP 的持久链接能够有效减小 TCP 创建链接和断开链接的次数,这样的好处是减小了服务器额外的负担,并提高总体 HTTP 的请求时长。
持久链接在 HTTP/1.1 中是默认开启的,因此你不须要专门为了持久链接去 HTTP 请求头设置信息,若是你不想要采用持久链接,能够在 HTTP 请求头中加上Connection: close。目前浏览器中对于同一个域名,默认容许同时创建 6 个 TCP 持久链接.学习
若是 TCP 通道中的某个请求由于某些缘由没有及时返回,那么就会阻塞后面的全部请求,这就是著名的队头阻塞的问题。
HTTP/1.1 中试图经过管线化的技术来解决队头阻塞的问题。HTTP/1.1 中的管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然能够整批发送请求,不过服务器依然须要根据请求顺序来回复浏览器的请求。
FireFox、Chrome 都作过管线化的试验,可是因为各类缘由,它们最终都放弃了管线化技术.测试
在 HTTP/1.0 中,每一个域名绑定了一个惟一的 IP 地址,所以一个服务器只能支持一个域名。
可是随着虚拟主机技术的发展,须要实如今一台物理主机上绑定多个虚拟主机,每一个虚拟主机都有本身的单独的域名,这些单独的域名都公用同一个 IP 地址。
所以,HTTP/1.1 的请求头中增长了 Host 字段,用来表示当前的域名地址,这样服务器就能够根据不一样的 Host 值作不一样的处理。优化
在设计 HTTP/1.0 时,须要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就能够根据设置的数据大小来接收数据。
不过随着服务器端的技术发展,不少页面的内容都是动态生成的,所以在传输数据以前并不知道最终的数据大小,这就致使了浏览器不知道什么时候会接收完全部的文件数据。 HTTP/1.1 经过引入 Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每一个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块做为发送数据完成的标志。这样就提供了对动态内容的支持。编码
除此以外,HTTP/1.1 还引入了客户端 Cookie 机制和安全机制。
HTTP/1.1为网络效率作了大量的优化,最核心的三种方式为:
- 增长了持久链接。
- 浏览器为每一个域名最多同时支持6个TCP持久链接。
- 使用CDN的实现域名分片机制。
HTTP/1.1对带宽的利用率却并不理想,这也是 HTTP/1.1 的一个核心问题. 带宽是指每秒最大能发送或者接收的字节数。咱们把每秒能发送的最大字节数称为上行带宽,每秒可以接收的最大字节数称为下行带宽。
出现宽带利用率不理想的缘由,主要为:
- 第一个缘由,TCP的慢启动。
- 第二个缘由,同时开启了多条TCP链接,那么这些链接会竞争固定的宽带。
- 第三个缘由,HTTP/1.1队头阻塞的问题。
HTTP/2 的解决方案能够总结为:一个域名只使用一个 TCP 长链接和消除队头阻塞问题.
具体实现就是:经过引入二进制分帧层,实现 HTTP 的多路复用技术。
- 能够设置请求的优先级。
- 服务器推送。
- 头部压缩。
HTTP/2 协议规范于 2015 年 5 月正式发布,在那以后,该协议已在互联网和万维网上获得了普遍的实现和部署。从目前的状况来看,国内外一些排名靠前的站点基本都实现了 HTTP/2 的部署。使用 HTTP/2 能带来 20%~60% 的效率提高,至于 20% 仍是 60% 要看优化的程度。总之,咱们也应该与时俱进,放弃 HTTP/1.1 和其性能优化方法,去“拥抱”HTTP/2
和一般同样,介绍 HTTP/3 以前,咱们先来看看 HTTP/2 到底有什么缺陷。
在 TCP 传输过程当中,因为单个数据包的丢失而形成的阻塞称为 TCP 上的队头阻塞。
有测试数据代表,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。
网络延迟又称为 RTT(Round Trip Time)。咱们把从浏览器发送一个数据包到服务器,再从服务器返回数据包到浏览器的整个往返时间称为 RTT。RTT 是反映网络性能的一个重要指标。
虽然咱们知道了TCP的队头阻塞和创建链接延时等缺点,可是经过改进TCP协议来解决这些问题很是困难,这里说的很是困难就是指TCP协议僵化。
TCP协议僵化体如今两个方面:第一个是中间设备的僵化;除中间设备的僵化外,操做系统也是致使TCP协议僵化的另一个缘由。
HTTP/3 选择了一个折衷的方法——UDP 协议,基于 UDP 实现了相似于 TCP 的多路数据流、传输可靠性等功能,咱们把这套功能称为 QUIC 协议。 HTTP/3 中的 QUIC 协议集合了如下几点功能:
- 实现了相似 TCP 的流量控制、传输可靠性的功能。虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增长了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其余一些 TCP 中存在的特性。
- 集成了 TLS 加密功能。
- 实现了 HTTP/2 中的多路复用功能。
- 实现了快速握手功能。
经过上面的分析,咱们相信在技术层面,HTTP/3 是个完美的协议。不过要将 HTTP/3 应用到实际环境中依然面临着诸多严峻的挑战,这些挑战主要来自于如下三个方面:
- 第一,从目前的状况来看,服务器和浏览器端都没有对 HTTP/3 提供比较完整的支持。Chrome 虽然在数年前就开始支持 Google 版本的 QUIC,可是这个版本的 QUIC 和官方的 QUIC 存在着很是大的差别。
- 第二,部署 HTTP/3 也存在着很是大的问题。由于系统内核对 UDP 的优化远远没有达到 TCP 的优化程度,这也是阻碍 QUIC 的一个重要缘由。
- 第三,中间设备僵化的问题。这些设备对 UDP 的优化程度远远低于 TCP,据统计使用 QUIC 协议时,大约有 3%~7% 的丢包率。