简体   繁体   English

对在 HTTP1 和 HTTP2 中发送请求感到困惑

[英]Confused about sending requests in HTTP1 and HTTP2

I learned that under HTTP1.1, the max number of default simultaneous persistent connections per host name (origin?) is going to be 6, at least for chrome.我了解到,在 HTTP1.1 下,每个主机名(来源?)的默认同时持续连接的最大数量将是 6,至少对于 chrome。 I am not asking about the exact number of the limit since I know it varies from browser to browser.我不是在询问限制的确切数量,因为我知道它因浏览器而异。 I am more curious about when we will open a new connection for new requests - does the browser reuse the same TCP connection somehow or it always starts a new TCP connection unless if it hasn't reached the limit of concurrent requests?我更好奇我们何时会为新请求打开新连接 - 浏览器是否以某种方式重用相同的 TCP 连接,或者它总是启动新的 TCP 连接,除非它没有达到并发请求的限制?

Let's say we are using HTTP1.1 and we have Connection: Keep-Alive if in the html we have假设我们使用的是 HTTP1.1 并且我们有Connection: Keep-Alive如果在 html 我们有

<script src="https://foo/foo1.js"></script>
<script src="https://foo/foo2.js"></script>
<script src="https://foo/foo3.js"></script>
<script src="https://foo/foo4.js"></script>
<script src="https://foo/foo5.js"></script>
<script src="https://foo/foo6.js"></script>
<script src="https://foo/foo7.js"></script>

will each one of the scripts result in a new TCP connection established or all the subsequent requests will reuse the first TCP connection established by the first script tab?每个脚本会导致建立一个新的 TCP 连接,还是所有后续请求将重用第一个脚本选项卡建立的第一个 TCP 连接? And if each one of these script result in a new TCP connection established, given the browser's limit for concurrent requests being 6, does the 7th request have to wait until the 6th request to be finished in order to establish the connection?如果这些脚本中的每一个都导致建立一个新的 TCP 连接,鉴于浏览器的并发请求限制为 6,第 7 个请求是否必须等到第 6 个请求完成才能建立连接?

The above example is about initiating requests from HTML tags.上面的例子是关于从 HTML 标签发起请求的。 What about api calls made from JavaScript?从 JavaScript 发出的 api 调用怎么样? Let's in our javascript we have让我们在我们的 javascript 中

const result1 = apiCall1()
const result2 = apiCall2()
const result3 = apiCall3()
const result4 = apiCall4()
const result5 = apiCall5()
const result6 = apiCall6()
const result7 = apiCall7()

And assume the endpoint that those API calls are hitting is all api.foo.com/v1/tasks , my questions are, again: will each one of the api call result in a new TCP connection established or all the subsequent requests will reuse the first TCP connection established by the first api call? And assume the endpoint that those API calls are hitting is all api.foo.com/v1/tasks , my questions are, again: will each one of the api call result in a new TCP connection established or all the subsequent requests will reuse the第一个 api 调用建立的第一个 TCP 连接? And if each one of these api call result in a new TCP connection established, given the browser's limit for concurrent requests being 6, does the 7th request have to wait until the 6th request to be finished in order to establish the connection?如果这些 api 调用中的每一个都导致建立新的 TCP 连接,鉴于浏览器的并发请求限制为 6,那么第 7 个请求是否必须等到第 6 个请求完成才能建立连接?

My last question is, compared to http1.1, does http2 address this problem by allowing sending many requests at the same time over one single TCP connection?我的最后一个问题是,与 http1.1 相比,http2 是否通过允许通过单个 TCP 连接同时发送多个请求来解决这个问题?

will each one of the scripts result in a new TCP connection established or all the subsequent requests will reuse the first TCP connection established by the first script tab?每个脚本会导致建立一个新的 TCP 连接,还是所有后续请求将重用第一个脚本选项卡建立的第一个 TCP 连接?

Actually that's a bad example since, by default, a <script> element is blocking so in that case it would execute them one by one and only move on to the next once the previous one had downloaded, parsed, and executed.实际上这是一个不好的例子,因为默认情况下,一个<script>元素是阻塞的,所以在这种情况下,它会一个一个地执行它们,并且只有在前一个元素下载、解析和执行后才会继续执行下一个元素。 So it only needs 1 TCP connection.所以它只需要 1 个 TCP 连接。

However if the were not blocking (eg had async or defer attributes) the.但是,如果没有阻塞(例如具有asyncdefer属性)。 Yes it would download them one by one, and start to open up more TCP connections to do that, up to the maximum of 6. The 7th request would have to wait for one of the connections to free up before it could be downloaded.是的,它会一个一个地下载它们,并开始打开更多的 TCP 连接,最多可达 6 个。第 7 个请求必须等待其中一个连接释放后才能下载。

But the reality is, that the first request may have finished by the time later TCP connections are opened so it might not quite reach the 6 limit for only 6 or 7 requests.但现实情况是,第一个请求可能在稍后 TCP 连接打开时已经完成,因此它可能不会完全达到 6 个限制,只有 6 个或 7 个请求。

What about api calls made from JavaScript?从 JavaScript 发出的 api 调用怎么样? Let's in our javascript让我们在我们的 javascript

Exact same thing.完全相同的事情。 Limit of 6 per origin.每个来源限制为 6 个。 Though one thing to note is certain CORS requests sent without credentials effectively counts as another origin (even though it's the same actual origin) and so get another 6 connections.尽管需要注意的一件事是某些 CORS 请求在没有凭据的情况下发送有效地算作另一个来源(即使它是相同的实际来源),因此获得另外 6 个连接。

My last question is, compared to http1.1, does http2 address this problem by allowing sending many requests at the same time over one single TCP connection?我的最后一个问题是,与 http1.1 相比,http2 是否通过允许通过单个 TCP 连接同时发送多个请求来解决这个问题?

Basically yes.基本上是的。 Not quite at the same time due to the way TCP works, but as near as possible.由于 TCP 的工作方式,不完全同时,但尽可能接近。 See my answer here: What does multiplexing mean in HTTP/2在这里查看我的答案: HTTP/2 中的多路复用意味着什么

The process is simple, if you assign keep-alive the connection is remembered for faster handshake so a user can make many requests without having to re-open a costly secure connection.该过程很简单,如果您指定保持活动状态,则会记住连接以加快握手速度,因此用户可以发出许多请求,而无需重新打开昂贵的安全连接。

Now there will always be the syn/ack process to make requests with the server.现在总会有 syn/ack 进程向服务器发出请求。 For the server to respond to every item your user requested a new connection is needed.为了让服务器响应您的用户请求的每个项目,需要一个新的连接。 There's bypassing this a little with cache to help your bandwidth and lessen the requests to server.使用缓存可以绕过这一点,以帮助您提高带宽并减少对服务器的请求。 All connections are ended upon request served.所有连接均应请求结束。

So in a scenario 100 browsers want to hit your site, each request looks like 1.js 2.js... The output should be in order but this can greatly depend on a lot of things.因此,在 100 个浏览器想要访问您的站点的场景中,每个请求看起来像 1.js 2.js... output 应该是有序的,但这在很大程度上取决于很多事情。 Your language you're coding in server-sided, how it's handled, serves and if you manage any queues.您在服务器端编写的语言、处理方式、服务方式以及您是否管理任何队列。 If you make a request that requires longer processing (will get back to you in the future) other requests could go ahead as long as you're not blocking the event loop (comes down to your server).如果您提出需要更长时间处理的请求(将来会回复您),只要您不阻塞事件循环(归结到您的服务器),其他请求可能会提前 go 。


Below you can see the process to establish a connection to the server, this is engaged each and every request.您可以在下面看到与服务器建立连接的过程,这涉及到每个请求。 The cost to TLS can be improved but initial request is expensive. TLS 的成本可以提高,但初始请求成本很高。 这个怎么运作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM