你如何在 NodeJS / Express 上优化 memory/cpu?
How do you optimise memory/cpu on NodeJS / Express?
我有一个基于 Express 构建的 Node 应用程序,它使用网络抓取工具来加载和解析数据。
我已经阅读了很多关于 NodeJS 的可扩展性和能够处理大量并发连接的内容,但是当您 运行 网络抓取工具(发送 1000 多个并发请求)时,我觉得开始有点崩溃了。
当 运行 时,我的服务器对其他 API 请求没有响应,并且 运行 多个实例同时导致速度慢如蜗牛。
我找不到任何关于限制是什么、它们应该是什么、我应该将多少请求集中在一起等等的文档。
我应该将我的爬虫请求限制为每秒 10 个吗?每秒 100 个?每秒 1000 个?或者我是否可以增加 VPS 上分配给我的节点进程的 CPU/memory 数量?
编辑:对于那些因为这个问题过于基于意见而投票结束的人,这就是我要问的具体内容:
- 一个 Express 应用在开始达到性能之前可以同时执行多少个 HTTP 请求
- 增加应用程序可用的内存/cpu 是否有任何帮助?
有很多不同的方法可以评估 Node 的性能。 Node 是 usually recommended for I/O bound workloads as opposed to CPU bound workloads,尽管它 运行 所使用的 V8 引擎在不断改进。
让 Node 执行的一个重要方面是以启用其 "non-blocking" 执行模型的方式进行编码。这意味着使用回调函数 and/or 承诺控制流,而不是传统的同步方法。如果您不编写异步代码,节点 将阻塞 ,因为事件循环将挂起需要任何 non-trivial 时间才能完成的代码。
I/O 可以(并且应该)与 Node 异步,但是 CPU-heavy 活动(比如在你抓取之后解析 .xml )不能(或不同程度) ), 所以事件循环最终会在每个长 CPU 任务上挂起。
要将此应用于您的特定用例并解决性能问题,如果您发布了一些爬虫的请求代码,可能会有所帮助。
注意:如果您已经理解这些概念并且这低于您的技能水平,我提前道歉。
我已经包含了一段代码,它启动了对一系列 .xml 资源的一系列请求,并将响应打印到控制台。如果您 运行 此代码,您会注意到打印 "out of order" 经常发生,因为每个请求可能需要不同的时间。给 http.request()
方法一个回调而不是使用同步版本的好处是,一旦请求开始,您的应用程序可以继续 运行 并接受新的请求。每次完成 Node 事件循环时,工作都可以逐步完成。
使用专门处理请求的库可以大大简化此代码片段。一个众所周知的叫做 request(恰当地命名),它可以帮助您的代码更简洁。
附带说明一下,在您的项目中大量使用 console.log()
会导致性能问题。
var http = require('http');
function getData(index) {
var options = {
'hostname' : 'example.com',
'path' : '/data' + index + '.xml',
'method' : 'GET'
};
var req = http.request(options, function(response) {
var fullText = "";
// listen for incoming data and add it to existing data
response.on('data', function(more) {
fullText += more;
});
// when request is complete, print it
response.on('end', function(done) {
console.log(fullText);
});
});
req.end();
// Do not fail silently, show error details
req.on('error', function(e) {
console.error(e);
});
}
for(var i = 0; i < 1000; ++i) {
getData(i);
}
我有一个基于 Express 构建的 Node 应用程序,它使用网络抓取工具来加载和解析数据。
我已经阅读了很多关于 NodeJS 的可扩展性和能够处理大量并发连接的内容,但是当您 运行 网络抓取工具(发送 1000 多个并发请求)时,我觉得开始有点崩溃了。
当 运行 时,我的服务器对其他 API 请求没有响应,并且 运行 多个实例同时导致速度慢如蜗牛。
我找不到任何关于限制是什么、它们应该是什么、我应该将多少请求集中在一起等等的文档。
我应该将我的爬虫请求限制为每秒 10 个吗?每秒 100 个?每秒 1000 个?或者我是否可以增加 VPS 上分配给我的节点进程的 CPU/memory 数量?
编辑:对于那些因为这个问题过于基于意见而投票结束的人,这就是我要问的具体内容:
- 一个 Express 应用在开始达到性能之前可以同时执行多少个 HTTP 请求
- 增加应用程序可用的内存/cpu 是否有任何帮助?
有很多不同的方法可以评估 Node 的性能。 Node 是 usually recommended for I/O bound workloads as opposed to CPU bound workloads,尽管它 运行 所使用的 V8 引擎在不断改进。
让 Node 执行的一个重要方面是以启用其 "non-blocking" 执行模型的方式进行编码。这意味着使用回调函数 and/or 承诺控制流,而不是传统的同步方法。如果您不编写异步代码,节点 将阻塞 ,因为事件循环将挂起需要任何 non-trivial 时间才能完成的代码。
I/O 可以(并且应该)与 Node 异步,但是 CPU-heavy 活动(比如在你抓取之后解析 .xml )不能(或不同程度) ), 所以事件循环最终会在每个长 CPU 任务上挂起。
要将此应用于您的特定用例并解决性能问题,如果您发布了一些爬虫的请求代码,可能会有所帮助。
注意:如果您已经理解这些概念并且这低于您的技能水平,我提前道歉。
我已经包含了一段代码,它启动了对一系列 .xml 资源的一系列请求,并将响应打印到控制台。如果您 运行 此代码,您会注意到打印 "out of order" 经常发生,因为每个请求可能需要不同的时间。给 http.request()
方法一个回调而不是使用同步版本的好处是,一旦请求开始,您的应用程序可以继续 运行 并接受新的请求。每次完成 Node 事件循环时,工作都可以逐步完成。
使用专门处理请求的库可以大大简化此代码片段。一个众所周知的叫做 request(恰当地命名),它可以帮助您的代码更简洁。
附带说明一下,在您的项目中大量使用 console.log()
会导致性能问题。
var http = require('http');
function getData(index) {
var options = {
'hostname' : 'example.com',
'path' : '/data' + index + '.xml',
'method' : 'GET'
};
var req = http.request(options, function(response) {
var fullText = "";
// listen for incoming data and add it to existing data
response.on('data', function(more) {
fullText += more;
});
// when request is complete, print it
response.on('end', function(done) {
console.log(fullText);
});
});
req.end();
// Do not fail silently, show error details
req.on('error', function(e) {
console.error(e);
});
}
for(var i = 0; i < 1000; ++i) {
getData(i);
}