ホームページ >ウェブフロントエンド >フロントエンドQ&A >NodeJS サービスが常にクラッシュする問題を解決する方法

NodeJS サービスが常にクラッシュする問題を解決する方法

醉折花枝作酒筹
醉折花枝作酒筹転載
2021-04-13 18:44:432534ブラウズ

この記事では、NodeJS サービスが常にクラッシュする問題を解決する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

NodeJS サービスが常にクラッシュする問題を解決する方法

NodeJS は速い、しかしシングルスレッドであるため不安定で安全性が低く、複雑なビジネスを扱うには適さない、そんなイメージを持っている人も多いと思います。これは、同時実行性の要件が高い単純なビジネス シナリオに適しています。

実際、NodeJS には「脆弱」な側面があります。単一スレッドのどこかで「処理されない」例外が生成されると、確かに Node.JS 全体がクラッシュして終了します。例を見てみましょう。 1 つの node-error.js のファイル:

var http = require('http');

var server = http.createServer(function (req, res) {

  //这里有个错误,params 是 undefined
  var ok = req.params.ok;

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World
');
});

server.listen(8080, '127.0.0.1');

console.log('Server running at http://127.0.0.1:8080/');

サービスを開始してアドレス バーでテストし、http://127.0.0.1:8080/ を見つけます。予想どおり、ノードがクラッシュしました

$ node node-error
Server running at http://127.0.0.1:8080/

c:githubscript
ode-error.js:5
  var ok = req.params.ok;
                     ^
TypeError: Cannot read property 'ok' of undefined
    at Server.<anonymous> (c:githubscript
ode-error.js:5:22)
    at Server.EventEmitter.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2108:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:121:23)
    at Socket.socket.ondata (http.js:1966:22)
    at TCP.onread (net.js:525:27)

なぜ解決策は何ですか?

実際、今日の Node.JS の開発では、この問題さえ解決できなければ、おそらく誰もそれを使用しないでしょう。

uncaughtException の使用

uncaughtException を使用して、キャッチされなかったエラーをグローバルにキャプチャできます。同時に、この関数の呼び出しスタックを出力することもできます。キャプチャ後、効果的に実行できます。例:

process.on('uncaughtException', function (err) {
  //打印出错误
  console.log(err);
  //打印出错误的调用栈方便调试
  console.log(err.stack);
});

これはノード プロセス内での保護と同じですが、多くの人がこの方法を支持していません。つまり、ノードの例外を完全には制御できません。 .JS。

try/catch の使用

コールバックの前に try/catch を追加して、スレッドの安全性を確保することもできます。

var http = require('http');

http.createServer(function(req, res) {
  try {
    handler(req, res);
  } catch(e) {
    console.log('
', e, '
', e.stack);
    try {
      res.end(e.stack);
    } catch(e) { }
  }
}).listen(8080, '127.0.0.1');

console.log('Server running at http://127.0.0.1:8080/');

var handler = function (req, res) {
  //Error Popuped
  var name = req.params.name;

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello ' + name);
};

このソリューションの利点は、エラーとコールスタックを、現在発生している Web ページに直接出力できることです。

フレームワークへの統合

標準 HTTP 応答処理は、次の図に示すように、一連のミドルウェア (HttpModule) を経て、最終的にハンドラーに到達します。

NodeJS サービスが常にクラッシュする問題を解決する方法## これらのミドルウェアとハ​​ンドラーには NodeJS の機能が 1 つあります。これらはすべてコールバック関数であり、実行時に Node がクラッシュする唯一の場所はコールバック関数です。この機能によれば、フレームワークに try/catch を統合するだけで例外問題を比較的完全に解決でき、他のユーザーのリクエストには影響しません。

実際、現在のほとんどすべての NodeJS WEB フレームワークがこれを行っています。たとえば、OurJS オープン ソース ブログのベースとなっている WebSvr

には、次のような例外処理コードがあります。 #
Line: 207

  try {
    handler(req, res);
  } catch(err) {
    var errorMsg
      = '
'
      + 'Error ' + new Date().toISOString() + ' ' + req.url
      + '
'
      + err.stack || err.message || 'unknow error'
      + '
'
      ;

    console.error(errorMsg);
    Settings.showError
      ? res.end('<pre class="brush:php;toolbar:false">' + errorMsg + '
')       : res.end();   }

それでは、コールバックで生成されないエラーについてはどうすればよいでしょうか?心配しないでください。実際、そのようなノード プログラムはまったく起動できません。

さらに、ノード自身のクラスターにも一定のフォールト トレランスがあります。nginx のワーカーとよく似ていますが、リソース (メモリ) の消費が若干多く、プログラミングはあまり便利ではありません。私たちの JS はこの設計を採用していません。

NodeJS プロセスの保護とエラー ログの記録

例外による Node.JS のクラッシュの問題は基本的に解決されましたが、100% 信頼できるプラットフォームはなく、依然としていくつかのエラーが発生しています。 Node の最下層からスローされる例外の中には、try/catch や uncaughtException ではキャッチできないものがあります。以前に ourjs を実行すると、基盤となるレイヤーによってスローされたファイル ストリーム読み取り例外が発生することがありました。これは基盤となる libuv のバグでした。Node.js は 0.10.21 で修正されました。

この状況に直面した場合、異常なクラッシュが発生した後すぐに NodeJS を復活できるように、nodejs アプリケーションにデーモン プロセスを追加する必要があります。

さらに、例外が二度と発生しないように、これらの例外をログに記録する必要があります。

ノードを使用してノードを保護する

node-forever は、保護機能とログ ログ機能を提供します。

[sudo] npm install forever

インストールは非常に簡単です

$ forever start simple-server.js
$ forever list
  [0] simple-server.js [ 24597, 24596 ]

使用も非常に簡単です

forever -o out.log -e err.log my-script.js

ログを読むこともできます

WEB_DIR='/var/www/ourjs'
WEB_APP='svr/ourjs.js'

#location of node you want to use
NODE_EXE=/root/local/bin/node

while true; do
    {
        $NODE_EXE $WEB_DIR/$WEB_APP config.magazine.js
        echo "Stopped unexpected, restarting 

"
    } 2>> $WEB_DIR/error.log
    sleep 1
done

使用シェルを使用してノードを保護するスクリプトを開始します

ノードを使用してリソースのオーバーヘッドを保護することは、少し大きくなる可能性があり、少し複雑でもあります。OurJS はブート時に直接スクリプトを開始します。プロセススレッドを保護します。 たとえば、debian に置かれた ourjs 起動ファイル: /etc/init.d/ourjs

このファイルは非常に単純で、起動オプションのみが含まれています。無限ループ while true; あまりにも多くのエラーがプロセスをブロックするのを防ぐため、各エラーの後にサービスが 1 秒ごとに再起動されます。


rrreee
エラーログも非常に簡単です。プロセスコンソールに直接入力して出力するだけです。エラーを error.log ファイルに記録します: 2>> $WEB_DIR/error.log この行の 2 はエラーを表します。


推奨学習:

JavaScript ビデオ チュートリアル


以上がNodeJS サービスが常にクラッシュする問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。