簡體   English   中英

在節點中控制多個進程

[英]Controlling Multiple Processes in Node

好吧,所以我有一個機器人托管的事情。 我現在唯一擁有的就是讓我保持理智。 這是一個用於音樂/聊天網站的IRC類型的機器人,它可以完成很多工作。 但是問題是使它們保持在線狀態。 我曾經使用過一個sh文件,它將永久永久地啟動所有bot。

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

等,等等。 但是,自動程序本身占用大約30mb的RAM,而永久進程也占用大約30mb的RAM。 因此,與我運行的機器人數量一樣,我在RAM上的內存已接近用盡,這不好,因為如果必須購買另一台服務器,事情對我來說將變得更加復雜,而且如果我說實話,我不太擅長此事。

因此,我做了一些研究,發現我只是使用child.fork()並使用一個bot.js生成其余的bot。 它工作得很漂亮,並將我的公羊使用率降低到不到原來的一半。 但是現在讓僵屍程序保持在線很痛苦。

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作業,該作業將一條消息發送給bot(不是節點消息,因為只要js文件正在運行,該消息就會返回,而如果bot已連接到服務則不會)從服務中獲取,並讓漫游器返回命令。 並且它設置了一個命令,以便如果它在15秒鍾內沒有收到機器人的響應,它將重新啟動它。 但是它似乎並非一直都在工作。 我很茫然。

任何幫助將不勝感激,如果可以的話,我將提供更多詳細信息。

看一下子堆棧的艦隊 一支機隊無人機可以管理所需的多個進程,並將自動重啟所有崩潰的進程。

艦隊的工作方式是建立一個集線器以及連接到該集線器的一架或多架無人機。 您可以使用git將代碼推送到中心。 集線器會自動將新版本的代碼部署到所有連接的無人機。 然后,您可以調用fleet spawn -- node foo.js Fleet將開始運行node foo.js ,如果崩潰將自動重新啟動foo.js

我的解決方案是在節點內使用流程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 ,最終每個進程exitCode stdoutstderr

這里的要點是一個可行的例子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM