首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

灵魂一问:一个TCP连接可以发多少个HTTP请求?

2019-12-24

一道经典的面试题是从 URL 在浏览器被输入到页面展示的进程中发生了什么,大多数答复都是说恳求呼应之后 DOM 怎样被构建,被制作出来。

图片来自 Pexels

可是你有没有想过,收到的 HTML 假如包括几十个图片标签,这些图片是以什么方法、什么次序、树立了多少衔接、运用什么协议被下载下来的呢?

要搞懂这个问题,咱们需求先处理下面五个问题:

先来谈谈第一个问题:现代浏览器在与服务器树立了一个 TCP 衔接后是否会在一个 HTTP 恳求完结后断开?什么情况下会断开?

在 HTTP 1.0 中,一个服务器在发送完一个 HTTP 呼应后,会断开 TCP 衔接。可是这样每次恳求都会从头树立和断开 TCP 衔接,价值过大。

所以尽管规范中没有设定,某些服务器对 Connection: keep-alive 的 Header 进行了支撑。

意思是说,完结这个 HTTP 恳求之后,不要断开 HTTP 恳求运用的 TCP 衔接。

这样的优点是衔接能够被从头运用,之后发送 HTTP 恳求的时分不需求从头树立 TCP 衔接,以及假如保持衔接,那么 SSL 的开支也能够防止,两张图片是我短时刻内两次拜访 Github.com 的时刻计算:

头一次拜访,有初始化衔接和 SSL 开支

初始化衔接和 SSL 开支消失了,阐明运用的是同一个 TCP 衔接

耐久衔接:已然保持 TCP 衔接优点这么多,HTTP 1.1 就把 Connection 头写进规范,而且默许敞开耐久衔接。

除非恳求中写明 Connection:close,那么浏览器和服务器之间是会保持一段时刻的 TCP 衔接,不会一个恳求完毕就断掉。

所以第一个问题的答案是:默许情况下树立 TCP 衔接不会断开,只要在恳求报头中声明 Connection:close 才会在恳求完结后封闭衔接。

详细文档见下面的链接:

https://tools.ietf.org/html/rfc2616#section-8.1 

第二个问题:一个 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 . 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 的。

可是,HTTP2 供给了 Multiplexing 多路传输特性,能够在一个 TCP 衔接中一起完结多个 HTTP 恳求。至于 Multiplexing 详细怎样完结的便是另一个问题了。

咱们能够看一下运用 HTTP2 的作用:

绿色是建议恳求到恳求回来的等待时刻,蓝色是呼应的下载时刻,能够看到都是在同一个 Connection,并行完结的。

所以这个问题也有了答案:在 HTTP 1.1 存在 Pipelining 技能能够完结这个多个恳求一起发送,可是因为浏览器默许封闭,所以能够以为这是不可行的。

在 HTTP2 中因为 Multiplexing 特色的存在,多个 HTTP 恳求能够在同一个 TCP 衔接中并行进行。

那么在 HTTP 1.1 年代,浏览器是怎么进步页面加载功率的呢?主要有下面两点:

第四个问题:为什么有的时分改写页面不需求从头树立 SSL 衔接?

在第一个问题的评论中已经有答案了,TCP 衔接有的时分会被浏览器和服务端保持一段时刻。TCP 不需求从头树立,SSL 天然也会用之前的。

第五个问题:浏览器对同一 Host 树立 TCP 衔接到数量有没有约束?

假定咱们还处在 HTTP 1.1 年代,那个时分没有多路传输,当浏览器拿到一个有几十张图片的网页该怎样办呢?

必定不能只开一个 TCP 衔接次序下载,那样用户必定等的很难过,可是假如每个图片都开一个 TCP 衔接发 HTTP 恳求,那电脑或许服务器都或许受不了。

要是有 1000 张图片的话总不能开 1000 个TCP 衔接吧,你的电脑赞同 NAT 也纷歧定会赞同。

所以答案是:有。Chrome 最多答应对同一个 Host 树立六个 TCP 衔接。不同的浏览器有一些差异。

https://developers.google.com/web/tools/chrome-devtools/network/issues#queued-or-stalled-requestsevelopers.google.com 

那么回到最开端的问题,收到的 HTML 假如包括几十个图片标签,这些图片是以什么方法、什么次序、树立了多少衔接、运用什么协议被下载下来的呢?

假如图片都是 HTTPS 衔接而且在同一个域名下,那么浏览器在 SSL 握手之后会和服务器商议能不能用 HTTP2,假如能的话就运用 Multiplexing 功用在这个衔接上进行多路传输。

不过也未必会一切挂在这个域名的资源都会运用一个 TCP 衔接去获取,可是能够确认的是 Multiplexing 很或许会被用到。

假如发现用不了 HTTP2 呢?或许用不了 HTTPS。

那浏览器就会在一个 Host 上树立多个 TCP 衔接,衔接数量的最大约束取决于浏览器设置,这些衔接会在闲暇的时分被浏览器用来发送新的恳求,假如一切的衔接都正在发送恳求呢?那其他的恳求就只能等等了。

热门文章

随机推荐

推荐文章