web-dev-qa-db-ja.com

NodeJSサーバーを正常に再起動する方法は?

現在、サイドプロジェクトのprod環境はgitリポジトリです。ここでは、コードを取得し、Ctrl-Cを使用してサーバーを手動で強制終了し、手動で再起動します。

これには多くの問題があることに気づきました。たとえば、ユーザーがまだ重要なことをしている最中で、プロセスが機密データを処理しているときに、私がそれを強制終了した場合はどうなりますか?!

ノードv0.4.xを使用したとき、アプリケーションがクワイエット状態のときにサーバーを正常に再起動できるNiceClusterモジュールがありました。 v0.6.xでは、クラスターモジュールはノードに組み込まれていますが、実際には、実際にはむき出しであり、正常な再起動機能はありません。

V0.6.xでnodejsサーバーを正常に再起動する方法を知っている人はいますか?

22
user1159470

ノードコードでPOSIXシグナルを処理できます。

SIGINT(たとえば、Ctrl-C)をすべてのクラスターワーカーのSTOPシグナルとして処理し、SIGUSR2がすべてのワーカーを再起動するサンプルコードを参照してください。

したがって、kill -SIGUSR2 PIDを発行すると、PIDはノードマスターPIDであり、すべてのクラスターが再起動します。

module.exports = function(app) {
    var cluster = require('cluster');
    var numCPUs = require('os').cpus().length;
    var workerList = new Array();
    var sigkill = false;

    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; i++) {
            var env = process.env;
            var worker = cluster.fork(env);
            workerList.Push(worker);
        }

        process.on('SIGUSR2',function(){
            console.log("Received SIGUSR2 from system");
            console.log("There are " + workerList.length + " workers running");
            workerList.forEach(function(worker){
                console.log("Sending STOP message to worker PID=" + worker.pid);
                worker.send({cmd: "stop"});
            });
        });

        process.on('SIGINT',function(){
            sigkill = true;
            process.exit();
        });

        cluster.on('death', function(worker) {
            if (sigkill) {
                logger.warn("SIGKINT received - not respawning workers");
                return;
            }
            var newWorker = cluster.fork();
            console.log('Worker ' + worker.pid + ' died and it will be re-spawned');

            removeWorkerFromListByPID(worker.pid);
            workerList.Push(newWorker);
        });
    } else {
        process.on('message', function(msg) {
            if (msg.cmd && msg.cmd == 'stop') {
                console.log("Received STOP signal from master");
                app.close();
                process.exit();
            }
        });
        app.listen(3000);
    }

    function removeWorkerFromListByPID(pid) {
        var counter = -1;
        workerList.forEach(function(worker){
            ++counter;
            if (worker.pid === pid) {
                workerList.splice(counter, 1);
            }
        });
    }
}
16
Andriy Samilyak

Forever という名前のモジュールがあります。

これにより、プロセスを正常に再開できます。そうすれば、クラスターを使用して複数のインスタンス(各コアに1つ)を実行し、Foreverを使用してそれらを監視/再起動できると思います。

これは私が見つけたオプションにすぎません。私は提案を受け入れます!

2
user1159470

PM2 という名前のモジュールもあります。クラスター内のすべてのプロセスを停止する機能があります。

1
Catfish