HTTP2 和 HTTP3
1.1. HTTP2
HTTP2 采用二进制传输将请求和数据切割为帧,帧对数据进行顺序标识多路复用,同域名下能达到一个 TCP 连接传输所有的请求数据都是基于流。
1.1.1 多路复用
多路复用代替了 HTTP1.1 的序列和阻塞机制,所有相同域名请求都通过同一个 TCP 连接并发完成。在HTTP1.1 中,并发多个请求需要多个 TCP 连接,浏览器为了控制资源会有 6-8 个 TCP 连接都限制。 如果开启了keep-alive,虽然可以用多次,但是同一时刻只能有一个 HTTP 请求。
1.1.2 header头压缩
header 第一次发送所有,之后发送差异。
头部压缩需要在支持 HTTP/2 的浏览器和服务端之间:
维护一份相同的静态字典(Static Table),包含常见的头部名称,以及特别常见的头部名称与值的组合;
维护一份相同的动态字典(Dynamic Table),可以动态地添加内容;
支持基于静态哈夫曼码表的哈夫曼编码(Huffman Coding);
静态字典的作用有两个:
1)对于完全匹配的头部键值对,例如 method: GET,可以直接使用一个字符表示;
2)对于头部名称可以匹配的键值对,例如 cookie: xxxxxxx,可以将名称使用一个字符表示。
1.1.3 HTTP2 缺点
- 如果有丢包请求会等待重传,阻塞后面的数据,有可能不如 HTTP1.1 的多个 TCP 连接;
- TCP 的队头阻塞并没有彻底解决,TCP 为了保证可靠传输,有一个“超时重传”机制,丢失的包必须等待重传确认;
- 多路复用导致服务器压力上升,多路复用没有限制同时请求数。请求的平均数量与往常相同,但实际会有许多请求的短暂爆发,导致瞬时 QPS 暴增;
- 多路复用容易 Timeout,大批量的请求同时发送,由于 HTTP2 连接内存在多个并行的流,而网络带宽和服务器资源有限,每个流的资源会被稀释,虽然它们开始时间相差更短,但却都可能超时。
1.2. HTTP3
是基于 UDP 的 QUIC 协议
- 解决掉 HTTP2 多路复用存在的丢包的问题,不存在阻塞多个流之前没有依赖,基于 ID 识别一个链接,不是 TCP 基于 IP 和端口;
- QUIC 可以在网络上保留更多的在途字节。在丢包率比较高的网络下,可以提升网络的恢复速度,减少重传量。
- 由于网络存在延迟丢包、接收端处理数据与发送端发送数据的速度有差别以及接收端可能采取收到多个包以后才统一回复 Ack 的策略,那么发送端就需要保存“已发送但未收到 Ack ”的数据列表,当触发重传时,直接在该链表中找到相应需要重传的数据,重传给接收端。