【问题标题】:Is there an equivalent of the async library but for node.js's child_processes除了 node.js 的 child_processes 之外,是否有等效的异步库
【发布时间】:2014-07-03 21:36:10
【问题描述】:

node 中流行的 async 库在处理 node 中异步函数的许多复杂控制结构方面做得很好。例如,假设我有一组银行账户 ID,我想从 API 中检索他们的余额,然后对结果余额求和。我可以通过执行以下操作以异步方式实现此目的:

var accountIds = [0001,0002,0003,0004,0005,0006]
async.mapLimit(accountIds,
  3,
  function fetchBalance(accountID, cbk) {
    var balanceURL = "http://someapi.com/account/balance/" + accountID;
    get(balanceURL, cbk);
  },
  function end(err, balances) {
    if (err) {
      console.err(err);
    }
    console.log(sum(balances));
  }
);

这使我不必编写管道来跟踪同时调度了多少异步函数,确保所有函数最终完成,跟踪错误等。此外,它在节点中运行良好,因为 I/O(在web请求的形式)是这个程序的限制因素。

但是,让我们想象一下,我们有受 CPU 限制的单个任务,而不是受 I/O 限制的单个任务。异步不会给我任何真正的性能优势,因为 node.js 只会运行一个主线程。在节点中并行化这种工作负载的一种解决方案可能是使用child_process 库并生成一堆工作进程来处理受 CPU 限制的工作。我的问题是,是否有一个库可以处理这些工作流的管道/协调,就像 async 对 I/O 绑定的异步函数所做的那样?如果没有,这值得写吗?我认为这可能是一个有趣的练习。

【问题讨论】:

    标签: node.js asynchronous parallel-processing


    【解决方案1】:

    我认为应该可以将 async 与 child_process 一起使用来实现您想要的。

    async.mapLimit(accountIds, 3, function(accountId, next) {
        child_process.execFile('myworker.js', [accountId], next);
    }, function(err, results) {
        console.log('done', err, results);
    });
    

    我想 spawn/fork 也可以使用,但你必须监听事件而不是回调来检查进程是否完成。

    显然myworker.js 应该进行一些繁重的计算,否则最终会比仅在主线程中进行计算要慢。来自nodejsdocumentationThese child Nodes are still whole new instances of V8. Assume at least 30ms startup and 10mb memory for each new Node. That is, you cannot create many thousands of them.

    如果您要经常使用这些流程,最好只创建一次并向它们发送消息以完成工作以避免启动成本。

    【讨论】:

    • 酷!很高兴知道至少有一个child_process 库函数需要回调。当我的论点将是一两个对象时,这似乎是合理的。如果我们谈论每个进程获得 10,000 多个帐户 ID 作为参数,但我们是否会被限制使用消息将它们传递给孩子?
    • 是的,如果你想传递数据,你需要使用某种 IPC。
    【解决方案2】:

    对于特定情况,可能有一个为 Node.js 构建的音频转换库。否则,您可以使用 lame 命令转换音频,但这意味着与 shell 命令交互的复杂性。

    一般来说,很容易设置一个 Express 服务器来公开类似 REST 的 URL。

    app.get('/path/:param', function(req, res, next) { CPUintensiveCalc(req.params.param, function(err, result) { res.send({ result: result}); }); });

    然后在另一个 Node.js 应用程序中,您可以使用 http.request 来调用服务。

    我在这里写了更长的回复:http://davidherron.com/blog/2014-07-03/easily-offload-your-cpu-intensive-nodejs-code-simple-express-based-rest-server

    【讨论】:

    • 嗯,我不确定您从哪里获得音频转换。此外,如果您将 CPU 密集型节点代码卸载到另一台服务器,您是否仍将阻塞 服务器的事件循环?如果您需要同时执行 2 个 CPU 密集型任务怎么办?
    猜你喜欢
    • 1970-01-01
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 2020-10-22
    • 2015-11-28
    相关资源
    最近更新 更多