找回密码
 立即注册
首页 业界区 业界 从HPACK到多路复用,揭秘HTTP/2如何终结网络拥堵 ...

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

嗳诿 昨天 23:44
头部压缩 (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),避免动态表无限增大。
1.png

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

在 HTTP/2 中,有二进制分帧之后,HTTP/2 不再依赖 TCP 链接去实现多流并行,而是基于多个并行流复用单TCP连接的方式来实现多路复用(Multiplexing):
1)同个域名只需要占用一个 TCP 连接,单个TCP 连接可以承载任意数量的双向流,这些流并行交错,之间互不干扰。
2)流以消息的形式发送,而消息又由一个或多个帧组成,不同流的帧是可以乱序发送,因为可以根据帧首部的流标识重新组装。同一个流内的帧必须是有序的。
流标识符是实现多路复用的关键,如下图,服务端并行交错地发送了两个响应: 流1和流 3,这两个流都是跑在一个TCP连接上,客户端收到后,会根据相同的流标识符有序组装成 HTTP 消息。
3.png

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

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

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册