卧虎藏龙
之前简单的介绍过,HTTP 是一种允许浏览器与服务器通信的协议,浏览器使用 HTTP 协议作为应用层协议,用来封装请求的文本信息。可是这 HTTP 的江湖,可不止这一角,不夸张的说,这里面卧虎藏龙呀。这还得从盘古开天辟地讲起...
HTTP/0.9
被设计用来在网络之间传递 HTML 超文本的内容,所以被称为超文本传输协议。基于请求响应模式,从客户端发出请求,服务器返回数据。当时简单的需求决定了它的局限:
- 只有请求行
- 服务器也没有返回头信息
- 返回的文件内容(HTML)以 ASCII 字符流来传输
HTTP/1.0
在浏览器中展示的不单是 HTML 文件了,还包括了 JavaScript、CSS、图片、音频、视频等不同类型的文件。因此支持多种类型的文件下载是 HTTP/1.0 的一个核心诉求,而且文件格式不仅仅局限于 ASCII 编码,还有很多其他类型编码的文件。为此 http1.0 新增:
- 请求头/响应头(浏览器和服务器的通信语言)
// 请求头-结束的形式
accept: text/html
accept-encoding: gzip, deflate, br
accept-Charset: ISO-8859-1,utf-8
accept-language: zh-CN,zh
User-Agent: xxx
// 响应头-最终返回的形式
content-encoding: br
content-type: text/html; charset=UTF-8
- 响应行状态码
- Cache
HTTP/1.1
默认持久连接
不成熟的管线化
HTTP/1.1 中试图通过管线化的技术来解决队头阻塞的问题。 HTTP/1.1 中的管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。
虚拟主机
一个 IP 对应一个物理主机,物理主机绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个 IP 地址。HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。
Chunk transfer 返回固定大小数据包可以在响应头设置
Content-Length: 404
告知浏览器;HTTP/1.1 通过引入 Chunk transfer 机制来解决动态内容无法确定大小的问题。服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。客户端 Cookie
安全机制
HTTP/2
即使使用了很多优化手段:增加了持久连接; 浏览器为每个域名最多同时维护 6 个 TCP 持久连接; 使用 CDN 的实现域名分片机制。 HTTP/1.1 的主要问题在于无法充分利用带宽,1000M 宽度理论下载速度是 12.5M/s,实际上只有 2.5M/s。限制在于:
- TCP 慢启动,慢启动是 TCP 为了减少网络拥塞的一种策略。每次传输数据包的大小成倍增加的
- 竞争带宽,发生在多条 TCP 连接之间,影响关键资源的下载。
- 队头阻塞,同一时刻只能处理一个请求
为了解决这些问题,HTTP2 特性就应运而生
一个域名使用一个 TCP 长连接
多路复用
在 HTTP 协议的下层加上二进制分帧层,请求数据经过处理后,转换成带上对应 ID 的帧,请求数据分帧传输。同理,响应数据应如是,这就实现了数据的随意发送、资源的并行传输。
设置请求优先级
服务器推送
头部压缩
HTTP/3
HTTP2 的局限主要在 TCP 协议上:
TCP 队头阻塞——丢包需要等待重传
因为只有一个 TCP 连接,所以随着丢包率的增加,HTTP/2 的传输效率也会越来越差。有测试数据表明,当系统达到了 2% 的丢包率时,HTTP/1.1 的传输效率反而比 HTTP/2 表现得更好。
TCP 建立连接的延时 网络延迟又称为 RTT(Round Trip Time)。从浏览器发送一个数据包到服务器,再从服务器返回数据包到浏览器的整个往返时间称为 RTT,RTT 是反映网络性能的一个重要指标。
TCP 连接的建立最少需要经过三次握手阶段,在传输数据之前,我们需要花掉 3 ~ 4 个 RTT。如果浏览器和服务器的物理距离较近,那么 1 个 RTT 的时间可能在 10 毫秒以内,也就是说总共要消耗掉 30 ~ 40 毫秒。如果服务器相隔较远,那么 1 个 RTT 就可能需要 100 毫秒以上了,这种情况下整个握手过程需要 300 ~ 400 毫秒。
由于中间设备的僵化,更换 TCP 协议的阻力很大,于是 HTTP3 基于 UDP 设计了 QUIC 协议:
- 提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性。
- 集成了 TLS 加密功能。
- 同一物理连接上可以有多个独立的逻辑数据流,解决了 TCP 中队头阻塞的问题。
Think
- 为什么是 HTTP2 而不是 HTTP1.2?
- 那为什么是 HTTP2 而不是 HTTP2.0?