我有一个基于Express的Node应用程序,它使用Web scraper加载和解析数据。
我已经阅读了很多关于NodeJS的可扩展性并且能够处理一堆并发连接,但是当你运行一个web scraper(发送1000多个并发请求)时,我觉得事情开始有点崩溃。
运行时,我的服务器对其他API请求没有响应,并且一次运行多个实例会导致速度降低到蜗牛的速度。
我找不到任何关于限制是什么,它们应该是什么,我应该聚集在一起的请求数等等的文档。
我应该将刮刀的要求限制为每秒10次吗?每秒100?每秒1000?或者我可能会增加在我的VPS上分配给我的节点进程的CPU /内存量?
编辑:对于那些投票结束的人,因为这个问题太基于意见,具体是我要问的是:
答案 0 :(得分:5)
评估Node的性能有很多不同的方法。节点是usually recommended for I/O bound workloads as opposed to CPU bound workloads,虽然它运行的V8引擎继续改进。
让Node执行的一个重要方面是以一种能够实现其非阻塞性的方式进行编码。执行模型。这意味着使用回调函数和/或控制流的承诺,而不是传统的同步方法。如果你不编写异步代码,节点将阻止,因为事件循环将挂起需要任何非常重要的时间来完成的代码。
> I / O可以(并且应该)与Node异步,但是CPU占用大量的活动(比如在刮掉它之后解析.xml)不能(或者不同程度),所以事件循环最终会挂起在每个长CPU任务上。要将此应用于您的特定用例并解决性能问题,如果您发布了一些刮刀的请求代码可能会有所帮助。
注意:如果您已经了解这些概念并且低于您的技能水平,我会提前道歉。
我已经提供了一段代码,可以启动对一系列.xml资源的一系列请求,并将响应打印到控制台。如果您运行此代码,您会注意到打印通常会发生"乱序",因为每个请求可能需要不同的时间。为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);
}