【问题标题】:How many child processes can a node server spawn?一个节点服务器可以产生多少个子进程?
【发布时间】:2021-08-13 09:32:59
【问题描述】:

我正在做一个 CPU 密集型的数学计算,因此我需要使用 node.js 生成一个子进程,因为它可能会阻塞主偶数循环。它不一定是内存密集型的,但它是 CPU 密集型的。以斐波那契数生成器为例。

我唯一担心的是我可能有很多用户,成千上万的用户同时在做这项工作,这意味着我将有数千个进程在我的 linux 机器上运行,因为 node.js 每次都会产生一个新进程child_process 运行。我的问题是一个 linux 服务器可以处理多少个进程?

注意:我的服务器是具有 4GB 内存的双核 linux VM。即,没有什么花哨的。 注意#2:我在这里寻找一个简单的球场图。以千计?谢谢。

【问题讨论】:

  • Waaaay 太宽泛了。我的上网本可以运行 NodeJS,然后答案是“不是很多”。把你的代码放在一个 24 核的 Haswell Xeon 机器上,它会为成千上万的人服务,因此我赞成这个过于广泛
  • 你能不能让它在用户之间共享部分计算,而不是一直为每个人做这件事?让我们假设 3000 个输入看起来相似,因此可以将中间步骤存储在某处。
  • Frederik,这是一个中肯的建议。谢谢。
  • +1 给弗雷德里克的建议。使用消息队列和与队列另一侧的 CPU 内核一样多的工作人员。立竿见影的好处:您现在可以轻松添加远程工作人员

标签: node.js


【解决方案1】:

两点……

  1. 如果您可以根据您的情况cache/memoize 结果,请这样做。
  2. 我会考虑使用generic-pool,以限制您对稀疏资源的使用。通过用节点池包装你的控制器,你可以限制自己在给定时间说 10 或 20 个活跃的工作人员。我自己做的物理 CPU 数量不会超过 2 倍,尽管您可以运行多少线程实际上取决于工作人员/系统。如果所有工作进程都相同,则更可预测。

【讨论】:

    【解决方案2】:

    没有足够公平的数字来说明可以处理多少个child_process,因为理论上它应该处理尽可能多的进程。

    这取决于您的 SLO(服务水平目标)。如果您希望您的应用程序在 100 毫秒内响应,您应该开始负载测试。

    例如

    你的主进程:

    const cluster = require('cluster'); 
    console.log(`master pid=${process.pid}`);
    cluster.setupMaster({
      exec: __dirname+'/child-process.js' 
    });
    cluster.fork(); 
    cluster.fork();
    
    cluster
      .on('disconnect', (worker) => { 
        console.log('disconnect', worker.id);
      })
      .on('exit', (worker, code, signal) => {
        console.log('exit', worker.id, code, signal);
        // cluster.fork(); 
      })
      .on('listening', (worker, {address, port}) => {
        console.log('listening', worker.id, `${address}:${port}`);
      });
    

    您的子进程:

    import express from 'express';
    
    const HOST = process.env.HOST || '127.0.0.1';
    const PORT = parseInt(process.env.PORT || '4000', 10);
    
    console.log(`worker pid=${process.pid}`);
    
    const app = express();
    app.get('sync/:limit', (req, res) => {
      res.send(fibonacci(Number(req.params.limit)));
    });
    
    app.listen(PORT, HOST, () => {
      console.log(`Running at http://${HOST}:${PORT}`);
    });
    
    function fibonacci(limit: number): string {
      let prev = 1n,
        next = 0n,
        swap: bigint;
    
      while (limit--) {
        swap = prev;
        prev = prev + next;
        next = swap;
      }
    
      return next.toString();
    }
    

    通过autocannon 运行您的测试

    $ autocannon -c 2 http://127.0.0.1:4000/100000
    

    它将向您显示延迟,现在您可以开始计算可以处理的最大化过程是什么

    Node.js 应用程序可能会变得复杂。进程通常以数十个(如果不是数百个)模块结束,这些模块建立外部连接、消耗内存或读取配置。这些操作中的每一个都可能暴露应用程序中可能导致其崩溃的另一个弱点。 因此,最好让主进程尽可能简单。

    推荐人Thomas Hunter. Distributed Systems with Node.js

    本书的推荐人implements

    但是,有一些方法可以帮助您提高服务处理能力。

    1. 使用负载平衡器并扩展您的服务。
    2. 缓存进程或结果。

    或者简单地限制传入以保持您的 SLO。

    【讨论】:

      猜你喜欢
      • 2017-07-15
      • 1970-01-01
      • 2022-10-13
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多