【译文】为什么你的浏览器会限制并发网络调用的数量?

每款浏览器都会限制单个域下边的并发连接数,当然对于总的并发连接数也有限制(一个网页资源涉及到的所有域)。

上边的图片来自于 StackOverflow。表明了不同浏览器支持的并发连接的数量。

浏览器为什么会限制调用的数量?

要搞清楚这个问题,我们首先需要搞明白当一个网络调用初始化时发生了什么。

发起一个网络调用发生了什么?

HTTP 1.0

当你使用ajax通过你的浏览器发起一个网络调用,或者当你请求存储在CDN的一个js或一个css文件,你的浏览器已经和服务器建立了一个TCP连接。此连接需要多次在客户端和服务端进行多次信息往返,这也被称为 握手(handshaking)

握手(handshaking)是两个参与者(客户端和服务端)之间通过消息交换的自动协商过程,该信息交换在完全通信之前通信开始时,建立网络通信线路协议。

所以基本上,当进行一个网络调用,在客户端和服务端之间建立一个隧道。

我们不能使用同一个TCP连接发出多个HTTP吗?

HTTP 1.1: Persistent connection

在HTTP 1.0中存在限制:一个连接只能发出一个请求。那也就是说,每发起一个网络请求,就需要建立一个新的连接通道。

因为建立连接是一个昂贵的过程,HTTP 1.1提出一个概念: 持久连接。(此特性也在HTTP 1.0的后期阶段被加入了)

持久连接就是在有限的时间段内连接保持打开状态,可以被多个请求重复使用,无需为每个连接请求进行新的TCP握手。

这个功能,我们可以通过一个相同的连接通道一个接一个的处理多个请求。

我们不能再单个连接中进行并发请求吗?

HTTP 1.1: HTTP Pipelining

现在我们拥有一个存在于客户端和服务端之间的隧道,但是我们在发第二个请求之前我们必须等待第一个请求的响应。

为了使并发请求成为可能,HTTP 1.1 提出另一个概念: Pipelining(翻译为管道或者流水线技术)

HTTP pipelining 是这样一种技术:其中多个http请求在单个连接通道上发送,而不需要等待相应的响应。
这也就是说,第二个请求不需要等待一个请求的响应。

下图(来自于Mozilla docs)解释了上述概念:

所以你的意思是我们可以使用 HTTP Pipelining处理任意数量的并发请求?

HTTP Pipelining确实加快了HTML页面的加载时间,但是随之而来也有许多问题。

第一个问题就是服务端发送响应的顺序必须和收到的请求的顺序保持一致 --- 所以整个连接保持 先进先出的原则。

另一个问题跟 HOL 阻塞有关系。

Head-of-line blocking (HOL blocking)是当一行数据包被第一个数据包阻塞时发生的性能限制现象。

因此大多数浏览器默认禁用此功能。

现在我们如何实现并发请求?

实现并发请求的唯一办法就是利用多个持久连接。

浏览器一次可以建立的连接数是多少?

这个问题的答案就是文章的开头部分。

尽管不同浏览器都有自己的限制,但是按照惯例,单用户客户端不应该与服务器保持2个以上的连接。

我们最初的问题是什么?为什么限制并发连接的数量?

现在,你可能已经意识到每一个连接都需要从服务器分配一些资源。此外,服务器需要维持每一个连接请求的信息,因此过多的连接数意味着服务器的负担很大。

另一个原因就是: DoS Attack. DOS(A Denial of Service) 攻击意味着让服务器忙于跟你打交道,以至于他无法跟其他客户端打交道。当其他客户端无法连接,这就是 DOS。

官网文档: 客户端使用持久连接应该限制同时连接的数量(到给定服务器维护的连接),一个单用户客户端与任何服务端或者代理服务器都不应该维持超过2个连接。一个代理服务器连接到另一个服务器或者代理,应该使用最多2*N个连接,N是同时活跃用户的数量。这些指南旨在改进HTTP响应时间和避免拥塞。

HTTP 2.0 怎么样

HTTP 2.0 也叫 SPDY,不像HTTP 1.X,它可以发起多个并发请求,详情参考 这里

并发调用是通过浏览器建立的并发连接通道来实现的。每一个连接都需要从服务器分配一些资源。此外,服务器必须维护每一个来自于客户端的连接请求的信息。此外,DOS 攻击的可能性很高。因此,服务端限制了来自于客户端的连接数量。

【原文】 Why does your browser limit the number of concurrent network calls?

posted @ 2021-06-28 23:56  韩帅  阅读(690)  评论(0编辑  收藏  举报