控制节点中的多个进程

时间:2013-04-07 20:18:15

标签: javascript node.js

好的,所以我有一个机器人托管我做的事情。这几乎是我现在唯一让我保持理智的东西。它是一个用于音乐/聊天网站的IRC类型的机器人,它做了很多事情。但问题是让他们保持在线。我以前使用sh文件,可以使用forever单独启动所有机器人。

cd dir/bots
forever start bot1.js
forever start bot2.js
...

等,等等。但机器人本身需要大约30mb的RAM,而永久的过程也需要大约30mb的RAM。因此,随着我运行的机器人数量众多,我的内存接近RAM,这并不好,因为如果我必须得到另一台服务器,对我来说事情会变得无比复杂,如果我是诚实的,我不是很擅长这个。

所以我做了一些研究,并认为我只是使用child.fork()并使用一个bot.js来生成其余的机器人。它的工作效果非常好,并将我的公羊用量减少到不到原来的一半。但现在让机器人保持在线是一件痛苦的事。

var child = require("child_process");
var running = {};
var bots = ["bot1","bot2","bot3"];
for (var i=0;i<bots.length;i++) { 
    running[bots[i]] = child.fork("bots/"+bots[i]+".js");
};

我的问题是 - 这是运行此设置的最有效方法吗?因为他们经常崩溃,如果我想以任何方式被认为是可靠的,他们需要非常自给自足,并且在我睡觉的时候在凌晨关闭。

现在我正在使用node-scheduler来创建一个假的cron作业,它向机器人发送消息(不是节点消息,因为只要js文件正在运行就会返回,而不是机器人是从服务连接到服务),并让机器人返回命令。它设置了一个命令,这样如果它在15秒内没有得到机器人的响应,它会重新启动它。但它似乎并不总是有效。我很茫然。

任何帮助都将不胜感激,如果可以,我会提供更多细节。

2 个答案:

答案 0 :(得分:0)

通过suback查看fleet。单个机群无人机可以根据需要管理任意数量的进程,并自动重启任何崩溃的进程。

Fleet通过设置集线器和连接到集线器的1个或多个无人机来工作。您使用git将代码推送到集线器。集线器会自动将新版本的代码部署到所有连接的无人机。然后你可以拨打fleet spawn -- node foo.js。 Fleet将开始运行node foo.js并在崩溃时自动重启foo.js

答案 1 :(得分:0)

我的解决方案是节点内的使用过程spawn,使用Promise模式同步流程执行,然后将结果与Promise.all结合起来(请参阅函数promiseAll此处:< / p>

var promiseAll = function(items, block, done, fail) {
    var self = this;
    var promises = [],
        index = 0;
    items.forEach(function(item) {
        promises.push(function(item, i) {
            return new Promise(function(resolve, reject) {
                if (block) {
                    block.apply(this, [item, index, resolve, reject]);
                }
            });
        }(item, ++index))
    });
    Promise.all(promises).then(function AcceptHandler(results) {
        if (done) done(results);
    }, function ErrorHandler(error) {
        if (fail) fail(error);
    });
}; //promiseAll 

现在进行导入

var cp = require('child_process');

并编写将生成每个进程的执行块:

var ExecutionBlock = function(item, index, resolve, reject) {
        var options = [
            "--ssl-protocol", "tlsv1",
            "--ignore-ssl-errors", "true"
        ];
        options.push(executableFile); // push input file path
        options.push(item); // push executable arguments
        // LP: now spawn the power!
        var child = spawn(settings.executable, options);
        // Listen for an exit event:
        child.on('exit', function(exitCode) {
            console.log("Child exited with code: " + exitCode);
            return resolve(exitCode);
        });
        // Listen for stdout data
        child.stdout.on('data', function(data) {
            console.log(data.toString());
        });
        // child error
        child.stderr.on('data',
            function(data) {
                console.log('err data: ' + data);
                // on error, kill this child
                child.kill();
                return reject(new Error(data.toString()));
            }
        );

    } //ExecutionBlock

此时,我们可以在inputItemsArray我们的可执行文件的参数列表中使用Promise.All方法运行它们:

// inputItemsArray is a list of arguments for the executable
promiseAll(inputItemsArray, function(item, index, resolve, reject) {
    ExecutionBlock(item, index, resolve, reject);
}
,function(results) { // aggregated results

    // all execution done here. The process exitCodes will be returned
    // array index is the index of the processed that exited
}
,function(error) { // error

});

完成块将汇总数组中的退出代码,因为我们已在resolve中返回它们。通过这种方式,您可以很好地控制执行,在执行期间为每个流程执行exitCode,最终stdoutstderr

要点here中的工作示例。