控制节点中的多个进程 [英] Controlling Multiple Processes in Node

查看:116
本文介绍了控制节点中的多个进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Okay, so I have a bot hosting thing I do. It's pretty much the only thing I have right now that's keeping me sane. It's an IRC type bot for a music/chat website, and it does a lot of things. But the problem is keeping them online. I used to use a sh file that would start all the bots individually with forever.

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

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

etc, etc. And that worked. But the bots themselves take around 30mb of RAM, while the forever process ALSO takes around 30mb of RAM. So with as many bots as I was running, I was near maxed out on RAM, and that wasn't good, because if I had to get another server, things would get infinitely more complicated for me, and if I'm being honest, I'm not very good at this.

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

So I did some research, and figured I'd just use child.fork() and use one bot.js to spawn the rest of the bots. And it works beautifully, and cut my ram useage down to less than half of what it was. But now it's a pain keeping the bots online.

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");
};

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

My question is - is this the most efficient way to run this setup? Because they are constantly crashing, and if I want to be considered reliable by any means, they need to be pretty self sufficient, and just shutting off in the wee hours of the night whilst I'm sleeping.

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

Right now I am using node-scheduler to create a fake cron job that sends a message to the bots (not a node message, because that would return as long as the js file is running, not if the bot is connected to the service) from the service, and have the bot return a command. And it sets a command, so that if it doesn't get a response from the bot in 15 seconds, it reboots it. But it doesn't seem to be working all the time. And I'm at a loss.

如果可以,我会提供更多详细信息。

Any help would be appreciated, and I'll provide more details if I can.

推荐答案

我的解决方案是在节点内使用进程 spawn ,使用 Promise 模式同步进程执行然后用 Promise.all 加入结果(参见函数 promiseAll here:

My solution is the use process spawn within node, use a Promise pattern to synchronize processes execution then join results with a Promise.all (see function promiseAll here:

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');

并写下将产生每个流程的执行块:

and write the execution block that will spawn each 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 方法运行它们:

At this point, supposed to have in inputItemsArray the list of the arguments of our executable, we can run them through the Promise.All approach:

// 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

});

完成块将聚合数组中的退出代码,因为我们已在<$ c中返回它们$ C>决心。通过这种方式,您可以很好地控制执行,为每个进程提供 exitCode ,最终 stdout 和<执行期间每个code> stderr 。

The completion block will aggregate exit codes in a array, since we have returned them in the resolve. In this way you can take a good control over the execution, having for each process the exitCode, eventual stdout and stderr for each of them, during the execution.

要点中的工作示例此处

这篇关于控制节点中的多个进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆