控制节点中的多个进程

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

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

等等等等,而且工作。 但机器人本身需要大约30MB的内存,而永远的进程也需要大约30mb的内存。 所以尽pipe有很多机器人在运行,但是我的内存已经接近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"); }; 

我的问题是 – 这是运行此设置最有效的方法吗? 因为他们不断地崩溃,如果我想以任何方式被认为是可靠的,他们需要相当的自给自足,并且在我睡觉的时候在晚上的凌晨关掉。

现在,我正在使用节点调度程序来创build一个假的cron作业,将消息发送给机器人(不是节点消息,因为只要js文件正在运行就会返回,而不是如果机器人连接到服务)从服务,并有机器人返回一个命令。 它会设置一个命令,如果它在15秒内没有得到机器人的响应,就会重新启动它。 但似乎并不是一直在工作。 而且我很茫然。

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

看看亚特兰蒂克船队 。 一个机队无人机可以pipe理尽可能多的进程,并且会自动重启任何崩溃的进程。

舰队的工作是build立一个枢纽和一个或多个连接到枢纽的无人机。 你用git把你的代码推到集线器上。 集线器会自动将新版本的代码部署到所有连接的无人机上。 然后你可以调用fleet spawn -- node foo.js 舰队将开始运行node foo.js ,并将自动重新启动foo.js,如果它崩溃

我的解决scheme是在节点中spawn使用过程,使用Promise模式来同步stream程执行,然后将结果与Promise.all (请参阅函数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'); 

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

 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

在这里的要点的一个工作的例子。