都 HTTP/3 了,HTTP/2 还不了解一下?
Posted 清远的梦呓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了都 HTTP/3 了,HTTP/2 还不了解一下?相关的知识,希望对你有一定的参考价值。
目录
源起
协议格式
分帧层
帧类型
首部压缩
交互流程
Curl 查看 HTTP/2
浏览器查看HTTP/2
其他
优化
使用率
不足
参考资料
源起
因为HTTP/1.1性能以及速度方面的问题,人们想了一系列的优化措施。当优化措施依然不能满足要求时,就需要对协议进行升级。于是,有了HTTP/2。
HTTP/2基于SPDY。SPDY 音同SPEEDY,也就是快,如果你看过 或者 ,那么也就知道这个套路了。
2009 年,Google 的工程师Mike Belshe 和Roberto Peon 提出了一种HTTP 的替代方案:SPDY。
SPDY 不是第一个希望替代HTTP 的方案,但它是其中最重要的一个,因为它带来了显而易见的性能提升。
SPDY为HTTP/2 奠定了基础,并证明了其中一些关键特性的合理性,如多路复用、帧和首部压缩等。SPDY很快被整合进了Chrome 和Firefox,并最终几乎被所有主流浏览器所采有。而且几乎在同一时间,服务器和网络代理也对SPDY 提供了必要的支持。
2012 年初,HTTP 工作组启动了开发下一个HTTP 版本的工作,其纲领的关键部分阐述了工作组对新协议的一些期望,HTTP/2 的主要目标是改进传输性能,实现低延迟和高吞吐量。
HTTP/2 被寄予了如下期望:
相比于使用TCP 的HTTP/1.1,最终用户可感知的多数延迟都有能够量化的显著改善;
解决HTTP 中的队头阻塞问题;
并行的实现机制不依赖与服务器建立多个连接,从而提升TCP 连接的利用率,特别是在拥塞控制方面;
保留HTTP/1.1 的语义,可以利用已有的文档资源(如上所述),包括(但不限于)HTTP 方法、状态码、URI 和首部字段;
明确定义HTTP/2 和HTTP/1.x 交互的方法,特别是通过中介时的方法(双向);明确指出它们可以被合理使用的新的扩展点和策略。
工作组发出了征求建议书的通知,并最终决定使用SPDY 作为HTTP/2 的起点。RFC 7540 在2015 年5 月14 日发布了,HTTP/2 成为正式协议。
HTTP/2浏览器支持情况:
备注:HTTP/2也写作HTTP2、H2
协议格式
分帧层
HTTP /2 性能增强的核心,全在于新增的二进制分帧层,它定义了如何封装HTTP 消息并在客户端与服务器之间传输。
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/6e265e8b90484c5ebfe538da23338a8b.jpg)
HTTP2二进制分帧层
这里所谓的“层”,指的是位于套接字接口与应用可见的高层HTTP API 之间的一个新机制。HTTP 的语义,包括各种动词、方法、首部,都不受影响,不同的是传输期间对它们的编码方式变了。HTTP/1 以换行符作为纯文本的分隔符,而HTTP2 将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码(HTTP为ASCII)。
所有HTTP/2 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。相应地,每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。
要理解HTTP/2,就必须理解流、消息和帧这几个基本概念。
所有通信都在一个 TCP 连接上完成(HTTP1,对单个域名,可能打开4~6个TCP连接)。
流是连接中的一个虚拟信道,可以承载双向的消息;每个流都有一个唯一的整数标识符(1、2…N)。
消息是指逻辑上的 HTTP 消息,比如请求、响应等,由一或多个帧组成。
帧是最小的通信单位,承载着特定类型的数据,如 HTTP 首部、负荷,等等
帧由帧首部和负载组成,帧首部长度相同,都是9个字节:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/33ffd9680d9045d0bfd1f29ccc99c4d3.jpg)
具体字段含义如下:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/febc79722e25471f81bfe0a5cb62a389.jpg)
帧类型
帧类型如下:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/7961a8090d1c4071adb7815662ecddb4.jpg)
1. DATA帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/39075d4ff83542879f2564bde409f632.jpg)
2. HEADERS帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/c817d8cdcac74f0ba759feb31b3dd3f6.jpg)
3. PRIORITY帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/6bf8126355db47619d65bdc3e3ac0d76.jpg)
4. RST_STREAM帧
关闭连接时使用,类似于TCP的RST。
5. SETTINGS帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/f2756daa98ef4198854a28c318a68592.jpg)
如果一端接收并处理了SETTINGS 帧,就必须返回一个SETTINGS 帧,在帧首部中带上ACK 标识(0x1)。这是SETTINGS 帧里定义的唯一的标识位。这样发送端就知道接收端收到了新的SETTINGS 帧,并会遵守SETTINGS 帧的设置。
6. PUSH_PROMISE帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/4ec0bb5d6faf41729f6345c4ffcb2920.jpg)
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/215f91a0a6ad462dbea16d71e439a648.jpg)
7. PING帧
作用类似于 ping 。
8. GOAWAY帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/fc69c7e8900f495c900fd2074d8d4837.jpg)
9. WINDOW_UPDATE帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/21a6feca352f45b0b1ce29d8cb4aa177.jpg)
备注:WINDOW_UPDATE 帧没有专用标识
10. CONTINUATION帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/86d3e3454bb44c7e801c0e1eec2a53fc.jpg)
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/dd13235798c6472e927a237b90dc1058.jpg)
首部压缩
HTTP 的每一次通信都会携带一组首部,用于描述传输的资源及其属性。在HTTP1 中,这些元数据都是以纯文本形式发送的,通常会给每个请求增加500~800 字节的负荷。如果算上HTTP cookie,增加的负荷通常会达到上千字节。为减少这些开销并提升性能,HTTP/2 会压缩首部元数据:
HTTP/2 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对
首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新
每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值
交互流程
HTTP2的交互流程:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/1c405c530b9641e1a98fca5990989737.jpg)
HTTP2流、消息和帧
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/8537818db8ac4e0f828b25b52abcbd8e.jpg)
HTTP2:多向请求和响应
HTTP/2 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。除了对最初请求的响应外,服务器还可以额外向客户端推送资源而无需客户端明确地请求。
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/8eb61be4df114c2a90a64d274c8c0c63.jpg)
HTTP2推送
Curl 查看 HTTP/2
通过curl查看HTTP2的交互流程:curl -v --http2 https://cn.bing.com
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/7e94de79466d4e48988c2de3d8a947af.jpg)
备注:H2即为HTTP/2
从交互可以看出cn.bing.com即支持HTTP/2,也支持HTTP/1.1,由于上层指定了HTTP/2,因此最终的交互流程是HTTP/2.
对应抓包如下:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/f7c9a97d4ae043b29e787502aff49f15.jpg)
在抓包中,我们也能看出当前走的是HTTP/2协议,任选TLSv1.2的Application Data行,并点开:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/02298313640843679b494abf7c20b40f.jpg)
抓包显示,也确实是HTTP/2协议。
HTTP/2默认支持HTTPS,端口为443。
如果不指定HTTP/2,输入命令:curl -v https://cn.bing.com,输出如下:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/fd8b4eca0cef4ceaa8f9cedb71e70f53.jpg)
对应抓包为:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/9469f9dbcf034dba845f244118fde016.jpg)
实际上,到这步,抓包中并没有显示到底是HTTP/2还是HTTP/1,任选TLSv1.2的Application Data行,并点开,看具体传输报文:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/9707015ea9514d3e9c2023f695910992.jpg)
备注:
在测试过程中,发现cn.bing.com有测不准原理,有些时候返回支持HTTP/2和HTTP1.1、有些时候只返回HTTP1.1(通过ALPN),因此即使指定了HTTP/2,也不一定走HTTP/2流程。
在测试时,即使不使用HTTP/2,curl也会用HTTP/2的方式。由于所使用的curl已经支持了HTTP/2,因此在向服务端发送Client Hello时,会通过ALPN告知服务端其能力,如果服务器支持HTTP/2,且选择了HTTP/2,那么即使不主动让curl以HTTP/2方式,其也可能以HTTP/2的方式进行交互。
浏览器查看HTTP/2
使用Firefox浏览器。
首先是默认方式访问并抓包:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/9d49f9b3b4834071b9b532ff9108e4e5.jpg)
抓包显示是HTTP/2,那么,Firefox是怎么知道要用HTTP/2呢?
在TLSv1.2的Client Hello报文中,有如下信息:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/0f28050a70ec45c6aadae69ce7688c9c.jpg)
报文显示,客户端向服务端发送的Client Hello报文中的ALPN部分表明了支持的协议为HTTP/2及HTTP1.1。
那么,看下服务端的Server Hello,信息如下:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/a658ec7b3acf4035b0b344ebf650a3f5.jpg)
报文显示,服务端选择了HTTP/2的交互方式,Application Data也确实显示是HTTP/2方式。
由于前面我们讲述了HTTP2的报文格式,抓包中Application Data报文是加密的,直接看不出来,为了看具体HTTP2报文格式,可以通过如下方式(Chrome 浏览器和FireFox浏览器):
-
设置用户变量:SSLKEYLOGFILE,值为会话密钥的存储文件(设置用户变量后,需要重启浏览器
2. 在Wireshark中设置密钥的路径:Edit-Preference-Protocols-SSL:
在浏览器中打开bing网站,并抓包:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/493ebb56a27340adb15add58b0e929a6.jpg)
可以看到,此时Wireshark已经能解密出具体报文了,并且显示出了具体的报文类型,譬如WINDOW_UPDATA报文。
进一步,过滤HTTP/2的报文:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/673f76eceb964a86b4c01e33b76b8d22.jpg)
以HEADERS报文为例,具体看一下抓包中的信息。
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/eddca4d169cb4efbaf192a2c948ddd14.jpg)
长度信息:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/18ae8a7c755842ad87be17c5b2ad8e6f.jpg)
前三字节为报文长度,值为0x027f,十进制为639
类型信息:
![都 HTTP/3 了,HTTP/2 还不了解一下?](https://image.cha138.com/20210426/54fe762d8bdb42c198483e424083cea2.jpg)
第4字节值类型为TYPE,值为0x01,为HEADERS报文
FireFox的HTTP/2是默认打开的,如果要使用HTTP1.1,得关闭这个使能:
浏览器中输入:about:config
输入:
network.http.spdy.enabled.http2,将这个配置置为false(双击即可)
其他
优化
为了加快访问速度,HTTP/1进行了一系列的优化,但是由于HTTP/2、采取了一些设计上的优势,因此HTTP/1的优化,有些HTTP/2抛弃了;有些依然保留,具体如下:
使用率
不足
由于HTTP/2采用的是TCP,TCP的那些问题依然存在,譬如TCP的队头阻塞问题依然没有解决。同时,TCP+TLS的方式导致交互时间很长,于是,人们提出了HTTP/3。HTTP/3的用法,可见,相关资料见该文中链接。
参考资料
1. 《HTTP权威指南》
2. 《HTTP/2基础教程》
3.《Web性能权威指南》
4. https://http2-explained.haxx.se/en
https://joji.me/zh-cn/blog/walkthrough-decrypt-ssl-tls-traffic-https-and-http2-in-wireshark/
以上是关于都 HTTP/3 了,HTTP/2 还不了解一下?的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 都转正成 Android 官方语言了,你还不试一下?
还不懂 ConcurrentHashMap ?这份源码分析了解一下