如何在 NodeJS / Express 上优化内存/CPU

How do you optimise memory/cpu on NodeJS / Express?

本文关键字:优化 内存 CPU Express NodeJS      更新时间:2023-09-26

我有一个基于Express构建的Node应用程序,它使用网络抓取工具来加载和解析数据。

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

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

我找不到任何关于限制是什么、它们应该是什么、我应该汇集多少请求等的文档。

我是否应该将刮板的请求限制为每秒 10 个?每秒 100 个?每秒 1000 个?或者我可以增加分配给我的 VPS 节点进程的 CPU/内存量吗?

编辑:对于那些因为这个问题过于基于意见而投票关闭的人,这是我提出的具体问题:

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

有很多不同的方法来评估 Node 的性能。通常建议将 Node 用于 I/O 密集型工作负载,而不是 CPU 密集型工作负载,尽管它运行的 V8 引擎仍在不断改进。

让 Node 执行的一个重要方面是以一种启用其"非阻塞"执行模型的方式进行编码。这意味着使用回调函数和/或承诺来控制流,而不是传统的同步方法。如果不编写异步代码,Node 将阻塞,因为事件循环将挂起需要任何非平凡时间才能完成的代码。

I/O 可以(并且应该)与 Node 异步,但 CPU 密集型活动(如在抓取后解析.xml)不能(或程度不同),因此事件循环最终将挂断每个长 CPU 任务。

要将其应用于您的特定用例并解决性能问题,如果您发布一些抓取工具的请求代码可能会有所帮助。

注意:如果您已经理解这些概念并且这低于您的技能水平,我提前道歉。

我包含了一个代码片段,用于启动对一系列.xml资源的一系列请求,并将响应打印到控制台。如果运行此代码,您会注意到打印通常会"无序"发生,因为每个请求可能需要不同的时间。为 http.request() 方法提供回调而不是使用同步版本的优点是,一旦请求启动,应用程序就可以继续运行并接受新请求。每次完成 Node 事件循环时,都可以增量完成工作。

通过使用专门处理请求的库,可以大大简化此代码片段。一个众所周知的称为请求(恰当地命名),它可以帮助您的代码更加简洁。

作为旁注,在项目中大量使用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);
}