2

この Node.js サーバーは、すべての接続が閉じられると、Ctrl+C で完全にシャットダウンします。

var http = require('http');
var app = http.createServer(function (req, res) {
  res.end('Hello');
});

process.on('SIGINT', function() {
  console.log('Closing...');
  app.close(function () {
    console.log('Closed.');
    process.exit();
  });
});

app.listen(3000);

これに関する問題は、キープアライブ接続が含まれていることです。Chrome でこのアプリのタブを開いて Ctrl+C を実行しようとすると、Chrome が最終的に接続を解放するまで約 2 分間シャットダウンしません。

一部の接続がまだ開いている場合でも、HTTP 要求がなくなったことを検出するクリーンな方法はありますか?

4

2 に答える 2

2

finish応答時のイベントを使用して、いくつかの要求追跡をハックできます。

var reqCount = 0;

var app = http.createServer(function (req, res) {
  reqCount++;
  res.on('finish', function() { reqCount--; });
  res.end('Hello');
});

サーバーを閉じるときに reqCount がゼロかどうかを確認できるようにします。

ただし、おそらく正しいことは、古いサーバーを気にせず、新しいサーバーを開始することです。通常、再起動は新しいコードを取得するためのものであるため、古いプロセスが終了するのを待たずに新しいプロセスを開始できます。オプションでchild_processモジュールを使用して、全体を管理するトップレベルのスクリプトを作成します。または、clusterモジュールを使用して、古いプロセスをシャットダウンする前に新しいプロセスを開始することもできます (cluster子インスタンス間のトラフィックのバランスを管理するため)。

私が実際にあまりテストしていないことの 1 つは、server.close()復帰後すぐに新しいサーバーを起動しても安全であることが保証されているかどうかです。そうでない場合、新しいサーバーがバインドに失敗する可能性があります。このようなエラーserver.listen()を処理する方法については、ドキュメントに例があります。EADDRINUSE

于 2013-03-05T16:52:52.493 に答える
2

デフォルトでは、ソケット タイムアウトはありません。つまり、クライアントが接続を閉じるまで、接続は永久に開かれます。タイムアウトを設定したい場合は、この関数を使用します: socket.setTimeout

サーバーを閉じようとしても、アクティブな接続があるため単にできません。そのため、正常にシャットダウンしようとすると、シャットダウン機能がハングアップします。唯一の方法は、タイムアウトを設定し、期限が切れたらアプリを強制終了することです。

ワーカーがいる場合、 でアプリを強制終了するほど簡単ではprocess.exit()ないので、あなたが求めていることを正確に実行するモジュールを作成しました: grace

于 2013-03-05T18:56:07.860 に答える