HTTP/1.1
特点:
- 简单:HTTP/1.1的报文格式包括头部和主体,头部信息是键值对的形式,使得其易于理解和使用。
- 灵活和易于扩展:HTTP/1.1的请求方法、URL、状态码、头字段等都可以自定义和扩展,使得其具有很高的灵活性。同时,其下层(如SSL/TLS,TCP/UDP)也可以随意变化。
- 跨平台表现良好:HTTP/1.1可以在各种操作系统和硬件平台上运行。
- 无状态:HTTP/1.1是无状态的,这意味着服务器不需要存储关于客户端的信息。这减轻了服务器的负担,但也意味着每次进行关联操作时都需要进行身份验证。为了解决这个问题,服务器可以存储Cookie来记录上次访问的信息。
- 长连接:HTTP/1.1支持长连接,即一次握手后可以进行多次请求-响应。
- 支持管道网络传输:虽然默认关闭,但HTTP/1.1支持管道网络传输,即发送第一个请求后无需等待响应就可以继续发送请求,但响应需要按顺序进行。如果前面的响应时间过长,可能会造成队头阻塞。
优化方法:
- 启用缓存:通过启用缓存,可以减少请求次数,从而提高效率。
- 减少重定向:重定向可能会导致额外的请求和响应,增加了延迟。如果存在代理服务器,可以让代理服务器直接发送新的URL请求,从而减少重定向的影响。
- 合并请求:由于HTTP/1.1默认关闭管道,可能会发生队头阻塞。通过合并请求,可以减少重复的HTTP头部和TCP连接过程。具体方法包括将多个小图片合并成大图片,使用webpack等打包工具,或者将图片数据用base64编码嵌入到HTML中。
- 延迟请求:在同一页面中,可以在用户需要时(如图片)再发送请求,从而减少不必要的请求。
- 压缩:可以使用无损压缩(如gzip、Brotli)来压缩文本和源代码,或者使用有损压缩(如Google的WebP格式)来压缩视频和图片,从而减少传输的数据量。
HTTP/2.0
-
兼容性:HTTP/2.0在语义层面上兼容HTTP/1.1,这意味着所有基于HTTP/1.1的应用都可以在HTTP/2.0上运行。但在语法方面,HTTP/2.0进行了一些升级和改进,以提高性能和效率。
-
头部压缩:HTTP/2.0引入了HPACK算法进行头部压缩,解决了HTTP/1.1中只能对body进行压缩的问题。HPACK算法包括静态字典、Huffman编码和动态字典三部分。静态字典包含常用的字段和字段值,用数字代替。Huffman编码则是根据字符出现的频率进行二进制编码。动态字典则是在通信过程中,根据实际的头部字段动态生成的。
-
二进制帧: HTTP/2.0引入了二进制分帧层,这是一个新的抽象层,位于应用层和传输层之间。在这个层次上,HTTP消息被分解为多个较小的消息和帧,然后进行交互。这种设计使得HTTP/2.0可以更有效地利用网络资源,提高传输效率。
每个帧都包含以下部分:
- 帧头:包括帧长度(表示帧数据的长度)、帧类型(定义帧的类型,如数据帧或头部帧)、标志位(提供帧相关的特定信息)和流标识符(唯一标识一个流)。
- 帧负载:帧的主体部分,包含由帧头描述的数据。
-
并发传输 :HTTP/2.0支持多个Stream复用一个TCP连接,每个HTTP请求与响应都在同一个Stream中进行,一个HTTP消息可以由多个Frame构成,一个Frame可以由多个TCP报文构成。
并发传输的特点:- 不同Stream的帧可以乱序发送:在一个TCP连接中,来自不同Stream的帧可以乱序发送,通过Stream ID来区分属于哪个Stream。
- 同一Stream内部的帧必须是严格有序的:在一个Stream中,帧的发送和接收必须是有序的,保证了消息的完整性和正确性。
- 双方都可以建立Stream:在一个TCP连接中,客户端和服务端都可以建立Stream,客户端的Stream ID为奇数,服务端的Stream ID为偶数。
- 同一个连接中的Stream ID不能复用:在一个TCP连接中,每个Stream ID只能被使用一次,当所有的Stream ID都被使用完后,需要发送GOAWAY帧来断开连接。
- 支持服务端主动推送:例如,当客户端请求一个HTML文件时,服务端可以主动推送与该HTML文件相关的CSS文件,这可以减少客户端的请求次数,提高加载速度。
HTTP/3.0
- 使用UDP + QUIC代替TCP:HTTP/3.0使用UDP + QUIC来代替TCP,解决了TCP的固有问题,如队头阻塞、握手延迟等。
- 帧结构:HTTP/3.0的帧结构与HTTP/2.0相同,都采用二进制帧。由于流控制使用QUIC协议,帧头选用帧类型和数据长度两个字段。这种结构使得HTTP/3.0可以更有效地利用网络资源,提高传输效率。
- 头部压缩使用QPACK:HTTP/3.0的头部压缩使用QPACK,类似于HPACK,但进行了一些改进,如静态字典扩大,使用QUIC特殊的两个单向流来同步动态表。这种设计使得HTTP/3.0的头部压缩更加高效。
- 无队头阻塞:HTTP/3.0通过给每个数据包赋予唯一标识,解决了HTTP/2.0中某个流的包丢失会影响整个TCP的问题。这种设计使得HTTP/3.0在面对网络丢包时,可以更快地恢复传输。
- 更快的连接建立:HTTP/3.0通过连接ID来实现,并且QUIC中包含了TLS1.3,在QUIC握手的同时进行TLS握手,从而实现更快的连接建立。这种设计使得HTTP/3.0在建立连接时,可以更快地开始数据传输。
- 连接迁移:HTTP/3.0使用连接ID来标记通信的两个端点,即使断开连接,只要仍保有上下文信息,就可以直接复用连接,解决了HTTP/2.0中网络切换需要重新连接的问题。这种设计使得HTTP/3.0在面对网络环境变化时,可以更快地恢复传输。