• 聊聊 HTTP/2 的多路复用


    大家好,我是前端西瓜哥。今天我们来聊聊 HTTP/2 的多路复用

    HTTP/1 下的请求,并不能很好地地利用带宽:一个 TCP 连接同时只能有一个 HTTP 请求和响应。如果正在发送一个 HTTP 请求,那其他的 HTTP 请求就得排队。

    这种排队会产生一个请求队列,当队头的请求发生意外(比如丢包、服务器响应缓慢),导致比平时要慢得多,就会导致后面的请求被延迟。这种情况我们称为 队头阻塞(Head-of-line blocking)。

    为了缓解这个问题,浏览器会对同一个域名建立多个 TCP 连接,来实现 HTTP 的并发。

    但这也对服务器造成不小的负担,所以浏览器做了限制,同一个域名下 TCP 连接数最多会在 6 ~ 8 个左右。

    如果网页一次性加载的资源太多,比如大量图片,6 个 TCP 连接数可能也会顶不住。为了解决一个问题,我们会使用 域名分片(Domain sharding) 的方法,就是将资源放到不同的域名下。

    比如将图片放到专门的 static.xxx.com ,或者 CDN。因为域名不同,所以总的 TCP 连接数就能突破 6 的限制。达到 域名数 x 6

    HTTP/1.1 有一个 pipeline 机制,意图解决不能并发的问题,但因为实现上的缺陷,实质上已经废弃。浏览器也默认关闭 pipeline。

    为了解决这个问题,HTTP/2 使用了 多路复用

    HTTP/2 引入了流(stream)和帧(frame)的概念。

    帧是最小的数据单位,HTTP 报文不再是原来的明文的 ASCII 编码,而是会被拆分成一个个的二进制形式的帧。帧上面除了 HTTP 数据,还包含数据长度、流标识符、帧类型等信息。

    流是一个建立连接后的双向的虚拟字节流,可以承载多个消息。帧通过自己的流 ID,确定自己属于哪个报文,就可以不按顺序进行请求响应了。

    HTTP/2 会将所有 HTTP 请求打散成帧,在一个 TCP 连接上做并发请求,充分利用 TCP 带宽。现在浏览器对于 HTTP2,只会建立一个 TCP 连接,减轻了服务端不小压力。

    例子

    我们举个例子讲解 HTTP/1 升级为 HTTP/2 后利用多路复用带来的优势。

    假设依次请求一个很大的 JS 文件,和一个很小的 CSS 文件。

    在 HTTP/1 时,TCP 的发送的包是这样的(JS 用多个 1 表示,CSS 用多个 2 表示):

    111111111111111111111111222
    
    • 1

    JS 很大,会让 CSS 延迟,我们可能希望比较小的 CSS 能早一点请求完,早一点做解析。而且 JS 一旦发生了意外发生阻塞,CSS 就更晚才能获取到了。

    现在我们用 HTTP/2,就变成了下面这样:

    121212111111111111111111111
    
    • 1

    因为并行的原因,CSS 不仅不用再担心 JS 导致的阻塞,还能更早请求并获取到资源。

    结尾

    HTTP/2 的多路复用能够解决 HTTP 队头阻塞问题,更充分地利用 TCP 带宽。

    但因为还是在 TCP 上的协议,所以不能解决 TCP 队头阻塞问题,这个问题要交给 HTTP/3 通过 UDP 来解决了,期待一下。

    我是前端西瓜哥,欢迎关注我,学习更多前端知识。

  • 相关阅读:
    人工智能的发展现状,AI将如何改变IT行业,哪些职业将最先失业
    概率的三条基本公理 | 布尔不等式的应用(举例)
    CF1036C Classy Numbers 题解
    【思科、华为、华三这三大认证,选哪个考最好?】
    ZYNQ7020开发(二):zynq linux系统编译
    17 | xml
    iptables防火墙
    C++ 惯用法之 Policy-based design
    leetcode-数组系列算法总结
    有了这几个刷题网站,还愁跳槽不涨薪?
  • 原文地址:https://blog.csdn.net/fe_watermelon/article/details/126433842