你如何优化NodeJS / Express上的内存/ CPU?

时间:2016-01-20 19:51:07

标签: javascript node.js express web-scraping vps

我有一个基于Express的Node应用程序,它使用Web scraper加载和解析数据。

我已经阅读了很多关于NodeJS的可扩展性并且能够处理一堆并发连接,但是当你运行一个web scraper(发送1000多个并发请求)时,我觉得事情开始有点崩溃。

运行时,我的服务器对其他API请求没有响应,并且一次运行多个实例会导致速度降低到蜗牛的速度。

我找不到任何关于限制是什么,它们应该是什么,我应该聚集在一起的请求数等等的文档。

我应该将刮刀的要求限制为每秒10次吗?每秒100?每秒1000?或者我可能会增加在我的VPS上分配给我的节点进程的CPU /内存量?

编辑:对于那些投票结束的人,因为这个问题太基于意见,具体是我要问的是:

  1. Express应用程序在开始达到性能之前可以同时执行多少次HTTP请求
  2. 增加应用程序可用的内存/ CPU是否有帮助?

1 个答案:

答案 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);
}