Node.js – 发送一个大对象到child_process很慢

我的用例如下:我从节点服务器向公共API进行大量的API调用。 有时反应很大,有时很小。 我的用例要求我将响应JSON串联起来。 我知道一个大的JSON作为响应将阻止我的事件循环。 经过一番研究,我决定使用child_process.forkparsing这些响应,以便其他API调用不需要等待。 我尝试从我的主进程发送一个30 MB的JSON文件到分叉的child_process。 subprocess需要很长的时间来挑选和parsingjson。 从孩子的过程中期待的回应并不是很大。 我只是想串并获得长度,并发回到主stream程。

我附上主和子代码。

var moment = require('moment'); var fs = require('fs'); var process = require('child_process'); var request = require('request'); var start_time = moment.utc().valueOf(); request({url: 'http://localhost:9009/bigjson'}, function (err, resp, body) { if (!err && resp.statusCode == 200) { console.log('Body Length : ' + body.length); var ls = process.fork("response_handler.js", 0); ls.on('message', function (message) { console.log(moment.utc().valueOf() - start_time); console.log(message); }); ls.on('close', function (code) { console.log('child process exited with code ' + code); }); ls.on('error', function (err) { console.log('Error : ' + err); }); ls.on('exit', function (code, signal) { console.log('Exit : code : ' + code + ' signal : ' + signal); }); } ls.send({content: body}); }); 

response_handler.js

 console.log("Process " + process.argv[2] + " at work "); process.on('message', function (json) { console.log('Before Parsing'); var x = JSON.stringify(json); console.log('After Parsing'); process.send({msg: 'Sending message from the child. total size is' + x.length}); }); 

有没有更好的方式来实现即时通讯的尝试? 一方面,我需要node.js的强大function来实现每秒1000次的API调用,但是有时候我会得到一个大的JSON,它会把事情搞砸。

你的任务似乎是IO绑定(获取30MB大小的JSON),其中节点的asynchronous性闪耀,以及CPU的限制(parsing30MB大小的JSON)asynchronous不能帮助你。

分叉过多的过程很快就成为一种资源浪费并降低了性能。 对于CPU绑定的任务,您只需要与核心一样多的进程即可。

我将使用一个单独的进程来执行对N个其他进程的获取和委托parsing,其中N(至多)是CPU核心数减1,并且使用某种forms的IPC进行进程通信。

一种select是使用Node的Cluster模块编排以上所有内容: https : //nodejs.org/docs/latest/api/cluster.html

使用这个模块,您可以让主进程在前期创build您的工作进程,而不必担心何时分叉,创build了多less进程等。IPC像process.sendprocess.on一样正常工作。 所以可能的工作stream程是:

  1. 应用程序启动:主进程创build一个“fetcher”和N“分析器”进程。
  2. fetcher会发送一个API端点的工作列表来处理并开始提取JSON,并将其发送回主进程。
  3. 在获取的每个JSON上,主发送给parsing器进程。 您可以循环方式使用它们,也可以在parsing器工作队列为空或运行时使用更复杂的方式向主进程发送信号。
  4. parsing器进程将生成的JSON对象发送回主。

请注意,IPC也有不小的开销,特别是在发送/接收大型对象时。 你甚至可以让fetcher做非常小的响应的parsing,而不是通过它们来避免这种情况。 这里的“小”大概是<32KB。

另请参见: 在Node中的进程之间发送数据是否昂贵/高效?