从HPACK到多路复用,揭秘HTTP/2如何终结网络拥堵

头部压缩 (HPACK)

在HTTP/1中,每个请求和响应都会发送大量重复的头部信息,比如 Cookie、User Agent、Accept 等,会使得大量带宽被这些冗余的数据占用。为了解决这个问题,HTTP/2引入了HPACK算法来压缩头部信息。HPACK算法有两个主要的特性。

1)静态表(Static Table)和动态表():用来存储头部字段。静态表包含了61 种常见的头部字段,如":method"、":path"等。动态表则是在会话过程中动态更新,它存储了最近使用的头部字段。同时HPACK会建立一种称为"索引"的机制,用于快速查找和引用两个表中的键值对。这样对于相同的键值对数据,只需发送对应的键值就行。

1)静态表 (Static Table): 预定义了61个常用的HTTP头部字段名及其常见值(如 :method: GET, accept-encoding: gzip, deflate)。这些条目有固定的索引。

2)动态表 (Dynamic Table): 在连接的生命周期内,由编码器和解码器共同维护。新遇到的或不适合静态表的头部键值对可以添加到动态表中,并赋予动态索引。后续传输相同的头部时,只需发送其索引。

3)霍夫曼编码:用来压缩头部字段的值。霍夫曼编码是一种可变长度编码方法,将较短的代码分配给出现机率高的字母,而较长的代码分配给出现机率低的字母。这样可以使编码之后的字符串的平均长度降低,从而达到压缩数据的目的。

需注意的是,HPACK只用于压缩HTTP头部信息。另外假如每次请求的头部信息不一样,也会导致动态表建立过多索引,从而导致占用太多内存。因此服务器会对一个连接上的请求数量做限制(http2_max_concurrent_Streams),避免动态表无限增大。

多路复用 (Multiplexing)

在HTTP/1中,如果想并发发送多个请求,必须创建多个TCP连接,每个 TCP 连接都要经过 TCP 握手、慢启动以及 TLS 握手过程,这些都很耗时。浏览器为了减少负载,会对同一域名下的TCP连接做限制,这样当请求量比较大时,会引起阻塞,如下图,Stalled 阻塞已经达到356ms。如果当前请求响应迟迟不来,那么后续的请求是无法发送的,也造成了队头阻塞(Head-of-line blocking)的问题。

在 HTTP/2 中,有二进制分帧之后,HTTP/2 不再依赖 TCP 链接去实现多流并行,而是基于多个并行流复用单TCP连接的方式来实现多路复用(Multiplexing):

1)同个域名只需要占用一个 TCP 连接,单个TCP 连接可以承载任意数量的双向流,这些流并行交错,之间互不干扰。

2)流以消息的形式发送,而消息又由一个或多个帧组成,不同流的帧是可以乱序发送,因为可以根据帧首部的流标识重新组装。同一个流内的帧必须是有序的。

流标识符是实现多路复用的关键,如下图,服务端并行交错地发送了两个响应: 流1和流 3,这两个流都是跑在一个TCP连接上,客户端收到后,会根据相同的流标识符有序组装成 HTTP 消息。

客户端和服务器可以建立双向流,服务端可以主动推送资源给客户端。 客户端建立的流必须是奇数号,而服务器建立的流必须是偶数号。

比如下图,流1是客户端向服务端请求的资源,属于客户端建立的流,所以该流的ID是奇数(数字 1);流 2 和 4 都是服务端主动向客户端推送的资源,属于服务端建立的流,所以这两个流的 ID 是偶数(数字 2 和 4)。

HTTP/2 还可以对每个流设置不同优先级,帧头中的"标志位"可以设置优先级,比如客户端访问 HTML/CSS 和图片资源时,希望服务器先传递 HTML/CSS,再传图片,那么就可以通过设置流的优先级来实现,以此提高用户体验。

未完待续

很高兴与你相遇!如果你喜欢本文内容,记得关注哦!

相关推荐
lidashent10 小时前
c语言-内存管理
java·c语言·rpc
wuyang-ligerj11 小时前
路由基础(二):路由表和FIB表
运维·网络·网络协议·智能路由器
weixin_pk13813212 小时前
Libvio网站与客户端访问故障排查指南(专业版)
网络协议
wuyang-ligerj13 小时前
OSPF协议(三)
运维·网络·网络协议·智能路由器
骑着猪狂飙13 小时前
iOS技术之通过Charles抓包http、https数据
网络协议·http·ios·https
MonkeyKing_sunyuhua13 小时前
什么是JSON-RPC 2.0,在项目中应该怎么使用
qt·rpc·json
tan77º14 小时前
【项目】分布式Json-RPC框架 - 抽象层与具象层实现
linux·服务器·c++·分布式·tcp/ip·rpc·json
猿饵块15 小时前
stl--std::map
开发语言·c++·rpc
郭京京20 小时前
计算机网络简介
网络协议·go