2

もともと、Robuts の Web サーバーを Node.js ベースで作成する方法について質問したいのですが。しかし、それは非常に大きくて曖昧な質問になる可能性があります。そこで、Robuts Web サーバーを作成するときに直面する、小さくて具体的な質問または課題に分けます。

だから、私が直面している課題の 1 つは、Node.js で未処理のエラーをすべてキャッチする方法ですか? 未処理のエラーによってNode.jsの実行が停止し、Webサーバーがダウンすることを望まないため、これを実行したいと考えています。

思いつく解決策は、サーバーの実行中のコード ブロックを try-catch ブロックに配置して、未処理のエラーをすべてキャッチすることです。ただし、非同期メソッドからエラーが発生した場合、これは機能しません。たとえば、私の Web サーバーは次のコードのようになります。

var fs = require('fs');
var http = require('http');

try {

    // Here is my main web server, it could happen errors by adding
    // more and more modules and functionalities to my server.
    // I need to catch all unhandled errors to prevent server from crashing
    // So, I put my whole server running in a try-catch block, but any error from
    // an async method could not be caught!
    http.createServer(function(req, res) {
        throw Error("An unhandled error happens!");
    }).listen(1234);

}catch (e){
    console.log("An unhandled error caught!")
}

console.log('Server is listening to port 1234');

それで、サーバーが停止しないようにするために、エラー処理の正しい方向に進んでいますか? または、サーバーをエラーから回復させる他のメカニズムがありますか?

4

3 に答える 3

4

ドメインを使用する必要があります。

すべてのサーバーをラップする 1 つのグローバル ドメインと、要求ごとに 1 つのドメイン。初期化中にエラーが発生した場合は、グローバル ドメインがエラーをキャッチするので、ログに記録し、いくつかのクリーンアップ タスクを実行して、サーバーを強制終了できます。リクエストからエラーが発生した場合は、最優先でログに記録し、他のリクエストの処理を続行します。これが、node.js が堅牢な Web サーバーを作成する方法です。

主な問題は、できる限り正常にシャットダウンしようとすることです。正常な終了とは、サーバーを強制終了する必要がある場合 (ctrl-c または sigint またはエラーなどから)、単純なことを行うのではなく、process.exit(1)データベース接続を閉じる、ファイルを閉じる、誰かに通知するなどのリソースをクリーンアップする必要があることを意味します。ハンドラーが呼び出されたときにイベント ループが機能せprocess.on("exit", ...)ず、非同期タスクを実行できないためです。

また、ワーカーを使用している場合、サーバーをシャットダウンする必要があるときにワーカーを適切にシャットダウンするにはどうすればよいでしょうか?

エクスプレスエラーをどのように処理しますか?

これらはすべて、正常なシャットダウンを常に保証するために実装するのがかなり複雑に思えます。それが私がした理由ですnode-grace

于 2013-03-29T13:42:13.417 に答える
2

コールバック関数内で try/catch を使用します。

var fs = require('fs');
var http = require('http');

try {
    http.createServer(function(req, res) {
        try{
            // some code trowing erors
        }catch(e){
             console.log("error: " + e);
        }
}).listen(1234);

}catch (e){
    console.log("An unhandled error caught!")
}

console.log('Server is listening to port 1234');

なぜそれが起こるのですか?非同期 http コールバックは、http サーバー コールバック関数を設定するコードと同じティックでは実行されません (さらに、その関数はサーバーが要求を受け取るたびに呼び出されます)。あなた自身を試してみてください:

 try{
      throw Error("An unhandled error happens!");
 }catch(e){
     console.log(e)
 }

と:

 try{
     process.nextTick(function(){
        throw Error("An unhandled error happens!")
     });
 }
 catch(e){
     console.log(e)
 }
于 2013-03-29T12:20:37.677 に答える
1

Express を使用するオプションがある場合は、かなり低レベルのhttpモジュールの代わりに Express を使用することをお勧めします。Express を使用すると、エラーを適切に処理できます。

var express = require('express');
var app     = express();

app.get('/', function(req, res) {
  throw Error("An unhandled error happens!");
});

app.use(function(err, req, res, next) {
  console.log('error', err);
  res.send(500); // send a proper HTTP 500 message back to the client
});

app.listen(1234);

console.log('Server is listening to port 1234');

それ以外の場合は、 Nodeのドメインモジュールを見てください。

于 2013-03-29T11:57:23.210 に答える