好的,所以我有一个机器人托管我做的事情。这几乎是我现在唯一让我保持理智的东西。它是一个用于音乐/聊天网站的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秒内没有得到机器人的响应,它会重新启动它。但它似乎并不总是有效。我很茫然。
任何帮助都将不胜感激,如果可以,我会提供更多细节。
答案 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
,最终stdout
和stderr
。
要点here中的工作示例。