当前位置:首页 > Web开发 > 正文

如果能的话就使用 Multiplexing 功能在这个连接上进行多路传输

2024-03-31 Web开发

  曾经有这么一道经典面试题:从 URL 在浏览器被被输入到页面展现的过程中产生了什么?相信大大都筹备过的同学都能回答出来,但是如果继续问:收到的 HTML 如果包罗几十个图片标签,这些图片是以什么方法、什么挨次、成立了几多连接、使用什么协议被下载下来的呢?

  要搞懂这个问题,我们需要先解决下面五个问题:

现代浏览器在与处事器成立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

一个 TCP 连接可以对应几个 HTTP 请求?

一个 TCP 连接中 HTTP 请求发送可以一起发送么(好比一起发三个请求,再三个响应一起接收)?

为什么有的时候刷新页面不需要从头成立 SSL 连接?

浏览器对同一 Host 成立 TCP 连接到数量有没有限制?

第一个问题

  现代浏览器在与处事器成立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?

  在 HTTP/1.0 中,一个处事器在发送完一个 HTTP 响应后,会断开 TCP 链接。但是这样每次请求城市从头成立和断开 TCP 连接,价钱过大。所以虽然标准中没有设定,某些处事器对 Connection: keep-alive 的 Header 进行了撑持。意思是说,完成这个 HTTP 请求之后,不要断开 HTTP 请求使用的 TCP 连接。这样的好处是连接可以被从头使用,之后发送 HTTP 请求的时候不需要从头成立 TCP 连接,以及如果维持连接,那么 SSL 的开销也可以制止,两张图片是我短时间内两次访谒 https://www.github.com 的时间统计:

技术图片

   头一次访谒,有初始化连接和 SSL 开销

技术图片

  初始化连接和 SSL 开销消掉了,说明使用的是同一个 TCP 连接

  长期连接:既然维持 TCP 连接好处这么多,HTTP/1.1 就把 Connection 头写进标准,并且默认开启长期连接,除非请求中写明 Connection: close,那么浏览器和处事器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断失。

  所以第一个问题的答案是:默认情况下成立 TCP 连接不会断开,只有在请求报头中声明 Connection: close 才会在请求完成后封锁连接。

第二个问题

  一个 TCP 连接可以对应几个 HTTP 请求?

  了解了第一个问题之后,其实这个问题已经有了答案,如果维持连接,一个 TCP 连接是可以发送多个 HTTP 请求的。

第三个问题

  一个 TCP 连接中 HTTP 请求发送可以一起发送么(好比一起发三个请求,再三个响应一起接收)?

  HTTP/1.1 存在一个问题,单个 TCP 连接在同一时刻只能措置惩罚惩罚一个请求,意思是说:两个请求的生命周期不能重叠,任意两个 HTTP 请求从开始到结束的时间在同一个 TCP 连接里不能重叠。

  虽然 HTTP/1.1 规范中规定了 Pipelining 来试图解决这个问题,但是这个成果在浏览器中默认是封锁的。

  先来看一下 Pipelining 是什么,RFC 2616 中规定了:

A client that supports persistent connections MAY "pipeline" its requests (i.e., send multiple requests without waiting for each response). A server MUST send its responses to those requests in the same order that the requests were received. 一个撑持长期连接的客户端可以在一个连接中发送多个请求(不需要期待任意请求的响应)。收到请求的处事器必需凭据请求收到的挨次发送响应。  

  至于标准为什么这么设定,我们可以概略猜测一个原因:由于 HTTP/1.1 是个文本协议,同时返回的内容也并不能区分对应于哪个发送的请求,所以挨次必需维持一致。好比你向处事器发送了两个请求 GET/query?q=A 和 GET/query?q=B,处事器返回了两个功效,浏览器是没有步伐按照响应功效来判断响应对应于哪一个请求的。

  Pipelining 这种设想看起来对照美好,但是在实践中会呈现许多问题:

一些代办代理处事器不能正确的措置惩罚惩罚 HTTP Pipelining。

正确的流水线实现是庞大的。

Head-of-line Blocking 连接头梗阻:在成立起一个 TCP 连接之后,假设客户端在这个连接持续向处事器发送了几个请求。凭据标准,处事器应该凭据收到请求的挨次返回功效,假设处事器在措置惩罚惩罚首个请求时花费了大量时间,那么后面所有的请求都需要等着首个请求结束才华响应。

  所以现代浏览器默认是不开启 HTTP Pipelining 的。

  但是,HTTP2 供给了 Multiplexing 多路传输特性,可以在一个 TCP 连接中同时完成多个 HTTP 请求。至于 Multiplexing 具体怎么实现的就是另一个问题了。我们可以看一下使用 HTTP2 的效果。

技术图片

  绿色是倡议请求到请求返回的期待时间,蓝色是响应的下载时间,可以看到都是在同一个 Connection,并行完成的

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/31299.html