http1
http0.9特点
- 只有一个请求行,并没有HTTP 请求头和请求体。
- 服务器也没有返回头信息
- 是返回的文件内容是以 ASCII 字符流来传输的
http1.0
- 引入了请求头和响应头
- 客户端告诉服务端:返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码。
- accept: text/htmlaccept-encoding: gzip, deflate, braccept-Charset: ISO-8859-1,utf-8accept-language: zh-CN,zh
- 服务端返回支持的压缩类型,文件语言和格式
- content-encoding: brcontent-type: text/html; charset=UTF-8
- 引入状态码
- Cache 机制,用来缓存已经下载过的数据
- 增加了用户代理UserAgent获取客户端的基础信息
http1.1
- 改进了tcp持久连接
- 尚未成熟的HTTP 管线化
- 原因:当新的tcp请求,需要等待前面的完成,如果前面一直卡主就会发生队头阻塞
- 管线化是指将多个 HTTP 请求整批提交给服务器的技术,虽然可以整批发送请求,不过服务器依然需要根据请求顺序来回复浏览器的请求。
- 提供虚拟主机的支持,新增host字段区分同一域名下的那一台主机
- 对动态内容的支持
- 在1.0里文件都是有明确的Content-length:100
- 很多文本其实是动态生成,无法告诉客户端具体的大小
- Chunk transfer 机制来解决这个问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。
- 客户端 Cookie、安全机制
http2
http1.1的缺点,宽带使用率不高
- tcp慢启动,为了避免启动暂用太多资源,策略是先慢后快
- 多个tcp会互相竞争资源,当网速不足时,部分tcp会进行降速处理
- http队头阻塞
- 管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。
解决方案
- 多路复用
- 一个域名只保留一个tcp,只有一次慢启动,也不存在资源竞争
- 对头阻塞是通过把所有数据分帧传输,服务端选择性返回
- 多路复用原理
- 在http 和 tcp中间 加入了 二进制分帧层
- http层数据会被转化为 一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器
- 服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。
- 然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。
- 二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。
- 浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求。
其他特征
http3
tcp的缺陷
- 依然没有解决tcp层面包的队头阻塞问题,而且http2一个域名只有一个tcp,当丢包严重更容易导致全停顿
- tcp 连接耗时
- 3次握手需要1.5个RTT,ssl 握手1-2RTT,共需要3-4个RTT
- Round Trip Time
- 浏览器发送一个数据包到服务器,再从服务器返回数据包到浏览器的整个往返时间称为 RTT
- TCP 协议僵化,升级tcp版本很难
解决方案-QUIC
- 实现了类似 TCP 的流量控制、传输可靠性的功能。
- 虽然 UDP 不提供可靠性的传输,但 QUIC 在 UDP 的基础之上增加了一层来保证数据可靠性传输。它提供了数据包重传、拥塞控制以及其他一些 TCP 中存在的特性。
- 集成了 TLS 加密功能。
- 实现了 HTTP/2 中的多路复用功能。
- 实现了在同一物理连接上可以有多个独立的逻辑数据流。实现了数据流的单独传输
- 实现了快速握手功能。
http3面临的困难
- 服务端和客户端对http3的支持不够
- 各个操作系统对UDP的优化没有TCP那么完善和成熟
- 中间设备不怎么支持UDP,导致丢包率高
参考
time.geekbang.org/column/intr…