聊聊 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

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

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

121212111111111111111111111

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

结尾

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值