HTTP1/2/3

http1.1
HTTP/1.1 的实现是基于请求-响应模型的。同一个连接中,HTTP 完成一个事务(请求与响应),才能处理下一个事务,也就是说在发出请求等待响应的过程中,是没办法做其他事情的,如果响应迟迟不来,那么后续的请求是无法发送的,也造成了队头阻塞的问题。
HTTP1.1是一种基于文本的协议,而HTTP2和HTTP3是基于二进制的协议。
HTTP1.1使用明文文本进行通信,而HTTP2和HTTP3使用二进制帧进行通信,这使得HTTP2和HTTP3可以更高效地传输数据。
HTTP/1.1 不支持服务器主动推送资源给客户端,都是由客户端向服务器发起请求后,才能获取到服务器响应的资源。HTTP2和HTTP3都支持服务器推送,可以在客户端请求之前向客户端发送资源,从而提高性能。
HTTP/1.1 报文中 Header 部分存在的问题:
含很多固定的字段,比如 Cookie、User Agent、Accept 等,这些字段加起来也高达几百字节甚至上千字节,所以有必要压缩;
大量的请求和响应的报文里有很多字段值都是重复的,这样会使得大量带宽被这些冗余的数据占用了,所以有必须要避免重复性;
字段是 ASCII 编码的,虽然易于人类观察,但效率低,所以有必要改成二进制编码;
HTTP/2 对 Header 部分做了大改造,把以上的问题都解决了。
HTTP/2 没使用常见的 gzip 压缩方式来压缩头部,而是开发了 HPACK 算法,HPACK 算法主要包含三个组成部分:
静态字典;
动态字典;
Huffman 编码(压缩算法);
对于常见的 HTTP 头部通过静态表和 Huffman 编码的方式,将体积压缩了近一半,而且针对后续的请求头部,还可以建立动态表,将体积压缩近 90%,大大提高了编码效率,同时节约了带宽资源。
http2
HTTP2引入了多路复用技术,允许在单个TCP连接上同时发送多个请求和响应,从而提高了性能。HTTP1.1只能在一个TCP连接上发送一个请求和响应。
多个 Stream 跑在一条 TCP 连接,同一个 HTTP 请求与响应是跑在同一个 Stream 中,HTTP 消息可以由多个 Frame 构成, 一个 Frame 可以由多个 TCP 报文构成。
在 HTTP/2 连接上,不同 Stream 的帧是可以乱序发送的(因此可以并发不同的 Stream ),因为每个帧的头部会携带 Stream ID 信息,所以接收端可以通过 Stream ID 有序组装成 HTTP 消息,而同一 Stream 内部的帧必须是严格有序的。
服务器支持主动推送资源,大大提升了消息的传输性能,服务器推送资源时,会先发送 PUSH_PROMISE 帧,告诉客户端接下来在哪个 Stream 发送资源,然后用偶数号 Stream 发送资源给客户端。
HTTP/2 通过头部压缩、二进制编码、多路复用、服务器推送等新特性大幅度提升了 HTTP/1.1 的性能,而美中不足的是 HTTP/2 协议是基于 TCP 实现的,于是存在的缺陷有三个。
队头阻塞;
TCP 与 TLS 的握手时延迟;
网络迁移需要重新连接;
队头阻塞:HTTP/2 多个请求是跑在一个 TCP 连接中的,那么当 TCP 丢包时,整个 TCP 都要等待重传,那么就会阻塞该 TCP 连接中的所有请求。因为 TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且有序的,如果序列号较低的 TCP 段在网络传输中丢失了,即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据,从 HTTP 视角看,就是请求被阻塞了。
握手延迟:发起 HTTP 请求时,需要经过 TCP 三次握手和 TLS 四次握手(TLS 1.2)的过程,因此共需要 3 个 RTT 的时延才能发出请求数据。
重新连接:一个 TCP 连接是由四元组(源 IP 地址,源端口,目标 IP 地址,目标端口)确定的,这意味着如果 IP 地址或者端口变动了,就会导致需要 TCP 与 TLS 重新握手,这不利于移动设备切换网络的场景,比如 4G 网络环境切换成 WiFi。
UDP 是一个简单、不可靠的传输协议,而且是 UDP 包之间是无序的,也没有依赖关系。UDP 是不需要连接的,也就不需要握手和挥手的过程,所以天然的就比 TCP 快。
HTTP/3 不仅仅只是简单将传输协议替换成了 UDP,还基于 UDP 协议在「应用层」实现了 QUIC 协议,它具有类似 TCP 的连接管理、拥塞窗口、流量控制的网络特性,相当于将不可靠传输的 UDP 协议变成“可靠”的了,所以不用担心数据包丢失的问题。
http3
HTTP/2只在应用层(HTTP层)解决了队头阻塞,但TCP层的阻塞仍然存在。HTTP/3通过QUIC解决了底层的队头阻塞问题,因为它在传输层就支持了多路复用和独立流的概念。
HTTP3使用QUIC协议,而HTTP1.1和HTTP2使用TCP协议。QUIC是基于UDP协议的,具有更好的性能和安全性。HTTP3还引入了0-RTT(零往返时间)握手,可以更快地建立连接。
QUIC 提供可靠、有序的加密握手数据传输。 QUIC 数据包保护用于尽可能多地加密握手协议。加密握手必须提供以下属性:
经过身份验证的密钥交换,其中
服务器始终经过身份验证,
客户端可以选择进行身份验证,
每个连接都会产生不同且不相关的密钥,并且
密钥材料可用于 0-RTT 和 1-RTT 数据包的数据包保护。
Last updated