1. Node.js 中的 Agent
在 Node.js 的官方文档中,对于 Agent 的定义是这样的:
一些 HTTP 客户端在重用套接字上有一定的技能。如果您正在进行许多请求,则会很耗费时间建立每个 TCP 连接。使用一个持久的套接字代理可以使某些请求的响应更快。此模块实现了 HTTP 代理 TCP 套接字的池。
当我们在使用 Node.js 建立 HTTP 客户端的时候,通过一系列的配置可以使用这个代理池,来确保我们的请求响应更快。而这个代理池中涉及到了一个重要的参数,该参数即是本篇文章的重点:maxSockets。
2. agent.maxSockets 属性介绍
简单来说,maxSockets 是 Agent 池中的最大套接字数。也就是说,在同一时间 Agent 可以同时发起的请求数不能超过这个数目。
在 Node.js v0.12.0 版本之前,Agent 的默认的 maxSockets 值是 Infinity,也就是说 Agent 可以不受限制的同时发起无数个请求。而从 v0.12.0 开始,maxSockets 默认值被设置为了 5,这意味着默认情况下 Agent 同时只能发起 5 个请求。当然,这只针对每个域名。
可以通过以下方式显式设置 maxSockets:
const http = require('http');
const keepAliveAgent = new http.Agent({keepAlive: true, maxSockets: 50});
http.request({
host: 'localhost',
port: 80,
path: '/',
method: 'GET',
agent: keepAliveAgent
}, res => {
// ...
});
从上面的代码中,我们可以看到,在创建一个 http.Agent 实例的时候,可以通过 maxSockets 来指定最大套接字数。这个 example 中,maxSockets 被设置为 50。
3. 为什么要设置 maxSockets
那么,我们为什么需要设置 maxSockets 呢?下面是一些重要原因:
3.1 控制请求发送速度
当同时发送的请求数超出了 Agent 的 maxSockets 限制时,剩余的请求数量会被暂时挂起,等到后续的请求结束之后才会继续发送。这样,即使是多个域名同时请求,也可以大大降低请求的发送速度,从而更加稳定地进行并行请求。
3.2 避免耗尽资源
设置 maxSockets 能够有效的避免消耗过多的系统资源。当没有限制请求发送速度,同时又有过多的请求在短时间内同时发送,这很容易耗尽系统的资源,导致服务崩溃。
4. 如何合理设置 maxSockets
上文提到了默认值,同时也说明默认值会在 Node.js 的版本更新中被更新。因此,建议根据自己的业务需求和系统配置,在手动设置时考虑到以下因素:
4.1 单一 IP 地址或域名的最大并发量
当并发请求数量非常大时,甚至会因为代理池被占满而出现连接超时或重连次数过多的情况。而一些大型服务商如 Google、Facebook 等都有单个 IP 地址或者域名的并发限制标准,一些小的服务商可能没有明确的标准。最好参考相应的文档来确认合适的此属性值。
4.2 系统硬件配置
在硬件配置低的情况下,maxSockets 可以尽可能倾向于慢一些的速度,以确保系统的可靠性。而对于硬件配置高的系统,则可以设置一个更高的值来加快请求速度。
4.3 Efficient Aggregation
Efficient Aggregation 是一种技术,即在服务器端尽可能多地合并同类或者近似的请求。 我们可以在前端合并每一次请求的职责,其原理类似于后端请求聚合的技术。同时设置 maxSockets,可以防止客户端同时提交过多的请求,这样服务器端在进行请求聚合时,避免出现大量无用请求。
5. 结论
合适的设置 maxSockets 值可以加快请求速度,提高响应效率。在开发中,对于某些需要大量请求某一接口或一段时间内需要快照和采集数据的应用,需要格外注意该参数的设置。在提升应用性能上,我们应该合理配置上述参数,控制请求速度。