2013-04-07 43 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中的一個工作示例。