我有一个Node.js应用程序,它基本上缓存来自Web服务的数据。 我还有一个队列,它接收大约500个需要尽快处理的项目。通过处理,我的意思是它们中的每一个代表一个HTTP请求以及它的缓存响应。
现在,Node的单线程架构并不适合这种情况。理想情况下,我想生成5-10个“线程”来尽快处理队列。我读到有一个child_process
模块可以分叉进程,但我从未使用它。这个模块能帮忙吗?
有人可以为这个问题提出解决方案吗?
答案 0 :(得分:2)
child_processes只是运行相同或不同脚本的新节点进程的分支。 您可以使用该API来生成系统进程,但这不是我将在此处描述的内容。
它们表现得像真正的nodejs进程,因为它们就是这样。
有一个很大的负面影响:
你需要记住,产生一个节点进程需要花费大量的时间和资源,因此通常可以更快地在一个节点进程中计算数据,或者生成工作者子进行通信工作。正如您在文档中看到的那样,您可以从child_process发送和接收数据,这使您能够将工作委派给已经生成的孩子。
子进程通常与生成它的进程共享相同的stdin和stdout,除非您更改它。只需看看文档。它有很好的文档记录,易于使用。
我从来没有让工人生孩子,但是我做了这样的事情,你可能认为这很有用。
if (process.argv.indexOf("child") == -1) {
process.chdir(module.filename.replace(/\/[^\/]+$/, ""));
var child;
var spawn = function () {
console.log("spawning child process " + new Date());
child = require("child_process").fork(module.filename, ["child"]);
child.on("close", function () {
spawn();
});
}
spawn();
process.on("exit", function () {
child.kill();
});
return;
}
// child code begins here
var fs = require("fs");
fs.watch(process.argv[1], function () {
process.exit();
});
答案 1 :(得分:0)
child_process模块会有所作为。
唯一的问题是,您实际上会产生新进程,因此,您需要考虑内存开销。假设您希望在同一文件中定义子例程的优雅,可以将JavaScript字符串传递给node
命令。
所以这正是我们要做的。但首先,让我们创建一个接受JSON兼容对象和函数的函数,然后在新线程上运行该函数:
var child_process = require('child_process');
function startThread(data, fn, callback) {
var fnStr = '(' + fn.toString() + ')(' + JSON.stringify(data) + ');';
var node = child_process.spawn('node', ['-e', fnStr]);
var output = [];
var onData = function (data) {
output.push(data.toString('utf8').trim());
};
node.stdout.on('data', onData);
node.stderr.on('data', onData);
node.on('close', function (code) {
callback(code, output);
});
}
作为一个例子,我们将产生一个新线程来生成“99瓶啤酒”的歌词:
startThread({ doFor: '99' }, function (data) {
var str = '';
while (data.doFor) {
str += data.doFor + ' bottles of beer on the wall ' + data.doFor +
' bottles of beer. You take one out, toss it around, ';
data.doFor--;
str += data.doFor + ' bottles of beer on the wall\n';
}
console.log(str.trim());
}, function (code, outputs) {
console.log(outputs.join(''));
});
不幸的是,将在另一个“线程”中使用的函数无法访问父线程中的变量。
此外,数据通过STDOUT和STDERR传递。