为什么在NodeJS上发出许多请求很慢



我用设置了一个本地快递服务器

const express = require('express');
const app = express();
app.get('/test', (request, response) => {
response.sendStatus(200);
});
const port = 3000;
app.listen(port, () => {});

然后我运行了一个脚本:

const axios = require('axios');
async function main() {
console.time('time');
const requests = Array(5000).fill().map(() => axios.get('http://localhost:3000/test'));
await Promise.all(requests);
console.timeEnd('time');
}
main();

我的问题是,为什么这个脚本在我的机器上需要3秒钟?

我预计它需要几毫秒的时间,就像其他5000次迭代的循环一样。因为我在本地运行服务器并通过localhost调用它,所以我预计不会有延迟,因此,promise的等待时间应该几乎为0。

有人能向我解释一下发生了什么事吗?

此外,我怎样才能更快地同时处理多个请求?

编辑

看这里https://stressgrid.com/blog/webserver_benchmark/我希望我的单进程节点服务器能够同时处理至少2万个请求,不会有任何延迟。

所以我猜我的机器上缺少一些配置。启动节点服务器时可能有一些标志?

3件事:

  • 该基准测试设置不正确
  • Express是所有NodeJS web框架中速度最慢的
  • 您的机器可能配置错误

您可以在这里找到更好的基准测试和不同框架的比较:https://www.fastify.io/benchmarks/

他们的github repo解释了他们所做的所有设置,所以你也可以将你的机器与他们的机器进行比较。

1。基准

简单地说,您设置的基准是无效的。它不会再现任何真实世界的场景,没有针对它创建的合成场景进行优化。

举个例子,因为在Node上,所有东西都是单线程的,所以串行运行请求会有更好的性能,这样连接就可以重用(还需要将请求框架更改为可以重用连接的框架(。如果您并行发出请求,HTTP1不会重用连接,而且您的客户端也没有设置为重用连接。

让我们来看看修复后的结果是什么样子的。在我的机器上,你发布的基准测试甚至没有运行——如果你试图在同一个端口上同时打开那么多连接,节点就会崩溃。这个版本的理论性能与你的基准测试差不多,它运行:

const axios = require("axios");
async function main() {
console.info(process.hrtime.bigint() / 1000000n + "ms");
for (let i = 0; i < 5000; ++i) {
await axios.get("http://localhost:3000/test");
}
console.info(process.hrtime.bigint() / 1000000n + "ms");
}
main();

在我的机器上大约需要3秒钟(和你的差不多(。现在让我们重用连接:

const axios = require("axios");
const http = require("http");
async function main() {
const httpAgent = new http.Agent({ keepAlive: true });
console.info(process.hrtime.bigint() / 1000000n + "ms");
for (let i = 0; i < 5000; ++i) {
await axios.get("http://localhost:3000/test", { httpAgent });
}
console.info(process.hrtime.bigint() / 1000000n + "ms");
}
main();

这需要800米。

您的基准测试遗漏了许多其他类似的细节。我不能把它们全部总结出来。您可以将您的基准与Fastify的基准进行比较(链接如上(,以了解每种差异如何影响您的测量。

2。框架

Express因其简单而广受欢迎,但它是而不是一个快速框架。看看更现代的,比如Koa或Fastify。请注意,您的应用程序可能不仅仅提供一个空页面,所以您的web框架的性能可能并不重要。也就是说,如果有选择的话,我认为任何人都不应该在2021年使用express,因为他们的开发经验也已经过时了(例如,不支持在中间件中等待请求(。

3。本地计算机

这也可能只是因为你的计算机速度慢等原因。这也是重新运行标准化基准而不是创建自己的基准的另一个原因。

首先定义慢速。您有Array(5000).fill(),我们可以将其解释为在内存中为我保留了5000个插槽,换句话说,您执行5000的for循环,然后执行5000请求,这意味着10000个循环。在java上执行同样的10000循环并进行比较,然后告诉我JavaScript是否慢。我也不知道你是否有,但axios有很多内部验证

最新更新