http1.1与http2
现在是2022年,不少网站都选择了采用http2技术
# 一、怎么看网站是不是http2
打开网站,按F12打开调试模式,选择Network,在表头的竖线间隙处单击鼠标右键,勾选上Protocol,默认没有勾选
h2代表是http2协议
某些网站可能会选择两种模式混用,知乎就是文本文件走http2,接口走的http1.1
# 二、http1.1有啥问题
现在我们先看一下 HTTP 发展到 1.1 存在有哪些问题:
线头阻塞:TCP 连接上只能发送一个请求,前面的请求未完成前,后续的请求都在排队等待。
多个 TCP 连接:1.1 版本请求并发依赖于多个 TCP 连接,建立 TCP 连接成本很高,还会存在慢启动的问题。
头部冗余,采用文本格式:HTTP/1.X 版本是采用文本格式,首部未压缩,而且每一个请求都会带上 cookie、user-agent 等完全相同的首部。
我们看看 http2 是怎么解决上面三个问题的
# 三、多路复用解决阻塞和并发问题
先看一个网络请求的瀑布图
打开控制台可以看到,HTTP/1.1 的方式,后面的图片的加载时间主要耗时在 stalled,stalled 的意思是从 TCP 连接建立完成,到真正可以传输数据之间的时间差。这就是队头阻塞,前面的请求没有处理,后面的请求都在排队等待。
HTTP2 的多路复用完美解决了线头阻塞问题。HTTP2 让所有的通信都在一个 TCP 连接上完成,真正实现了请求的并发。我们来看一下 HTTP2 具体是怎么实现的:
HTTP2 建立一个 TCP 连接,一个连接上面可以有任意多个流(stream),消息分割成一个或多个帧在流里面传输。帧传输过去以后,再进行重组,形成一个完整的请求或响应。这使得所有的请求或响应都无法阻塞。
这是采用了http2的apple官网 (opens new window)
我们可以看到stalled的等待时间非常短,几乎可以忽略不计
# 四、头部压缩解决头部冗余问题
在1.X版本中,首部用文本格式传输,通常会给每个传输增加500-800字节的开销。现在打开一个网页上百个请求已是常态,而每个请求带的一些首部字段都是相同的,例如cookie、user-agent等。
HTTP2为此采用HPACK压缩格式来压缩首部。头部压缩需要在浏览器和服务器端相互配合,维护一套header字典 (opens new window)
字典部分内容
我们在传输首部字段的时候,例如要传输method:GET,那我们只需要传输静态字典里面method:GET对应的索引值就可以了,一个字节搞定。像user-agent、cookie这种静态字典里面只有首部名称而没有值的首部,第一次传输需要user-agent在静态字典中的索引以及他的值,值会采用静态Huffman编码来减小体积。
example:
第一次传输过user-agent 之后呢,浏览器和服务器端就会把它添加到自己的动态字典中。后续传输就可以传输索引了,一个字节搞定。
# 五、怎么启用http2
前置条件
- nginx版本不低于1.9.5版本
- openSSL版本不低于1.0.2版本
- 已配置 HTTPS
server {
# 添加 http2
listen 443 ssl http2;
...
}
2
3
4
5
6
重启nginx
之后可以通过前面的方法验证是否开启