19

UNIXソケットをセットアップしてプロセス間通信チャネル(ある種の監視用のもの)を公開するNodeJSアプリケーションがあります。UNIX ソケット ファイルは、os.tmpdir()フォルダ (つまり/tmp/app-monitor.sock) に配置されます。

var net = require('net');
var server = net.createServer(...);
server.listen('/tmp/app-monitor.sock', ...);

シグナル処理 (SIGINT、SITERM など) を使用して、サーバーを正常にシャットダウンし、ソケット ファイルを削除します。

function shutdown() {
    server.close(); // socket file is automatically removed here
    process.exit();
}

process.on('SIGINT', shutdown);
// and so on

私のアプリケーションは、forever start ...ライフサイクルを監視するために実行されています。

コマンドに問題がありforever restartallます。永遠に行うときは、すべての子プロセスを終了するためにrestartalla を使用しています。プロセスで処理できないため、シャットダウン手順なしでアプリが終了します。SIGKILLSIGKILL

問題は、使用時に削除されないソケット ファイルですSIGKILL。子プロセスが再起動された後、新しいサーバーを起動できず、listen呼び出しによってEADDRINUSEエラーが発生します。

アプリの起動中に既存のソケット ファイルを削除できません。実際に動作しているソケットなのか、以前のクリーンでないシャットダウンの痕跡なのかわかりません。

それで、質問は...そのような状況を処理するためのより良い方法は何ですか(SIGKILLおよびUNIXソケットサーバー)?

4

5 に答える 5

47

他の人が言及しているように、SIGKILL に応答して何もすることはできません。これがforever、極端な状況を除いて、一般に (および他のすべての人が) SIGKILL を使用すべきではない理由です。したがって、最善の方法は、別のプロセスでクリーンアップすることです。

開始時にクリーンアップすることをお勧めします。が表示されたらEADDRINUSE、ソケットに接続してみてください。ソケット接続が成功した場合、別のサーバーが実行されているため、このインスタンスは終了する必要があります。接続に失敗した場合は、ソケット ファイルのリンクを解除して新しいファイルを作成しても安全です。

var fs = require('fs');
var net = require('net');
var server = net.createServer(function(c) { //'connection' listener
    console.log('server connected');
    c.on('end', function() {
        console.log('server disconnected');
    });
    c.write('hello\r\n');
    c.pipe(c);
});

server.on('error', function (e) {
    if (e.code == 'EADDRINUSE') {
        var clientSocket = new net.Socket();
        clientSocket.on('error', function(e) { // handle error trying to talk to server
            if (e.code == 'ECONNREFUSED') {  // No other server listening
                fs.unlinkSync('/tmp/app-monitor.sock');
                server.listen('/tmp/app-monitor.sock', function() { //'listening' listener
                    console.log('server recovered');
                });
            }
        });
        clientSocket.connect({path: '/tmp/app-monitor.sock'}, function() { 
            console.log('Server running, giving up...');
            process.exit();
        });
    }
});

server.listen('/tmp/app-monitor.sock', function() { //'listening' listener
    console.log('server bound');
});
于 2013-05-11T23:26:42.717 に答える
2

SIGTERM を使用して、必要なことを実行できるはずです。 process.on('SIGTERM', shutdown)

于 2013-05-07T21:26:15.620 に答える
1

処理できずSIGKILL、永久に使用したい (これは を使用しますSIGKILL) ため、回避策を使用する必要があります。

たとえば、最初にシグナルを送信してサーバーをシャットダウンしてから、永久に再起動します。

kill -s SIGUSR1 $pid
# $pid contains the pid of your node process, or use
# killall -SIGUSR1 node

sleep 2
forever restart test.js

あなたのjsハンドルでSIGUSR1:

process.on('SIGUSR1', gracefullyShutdownMyServer);
于 2013-05-08T19:56:39.947 に答える
0

あなたは選ばなければなりません

  1. アプリで処理するために、SIGKILLをforever-monitorの別のシグナルに変更します
  2. この場合、 fs.unlink を使用してアプリを管理してください
  3. 永遠に使うのをやめる
于 2013-05-09T13:56:33.830 に答える