2013-04-07 40 views
2

好吧,所以我有一个机器人托管我做的事情。这几乎是我现在唯一能让我保持健康的东西。这是一个音乐/聊天网站的IRC类型的机器人,它做了很多事情。但问题是让他们保持在线状态。我曾经使用sh文件来启动所有机器人,分别使用forever控制节点中的多个进程

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

等,而且工作。但机器人本身需要大约30MB的RAM,而永远的进程ALSO需要大约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秒内没有得到机器人的响应,它会重新启动它。但它似乎并不是一直在工作。而我不知所措。

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

回答

0

看看fleet由substack。单个机队无人机可以根据需要管理尽可能多的进程,并自动重启任何崩溃的进程。

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

0

我的解决办法是节点内的使用过程中spawn,使用Promise模式同步过程的执行,然后加入结果与Promise.all(见功能promiseAll这里:

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中的一个工作示例。