この記事では、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 を使用して、キャッチされなかったエラーをグローバルにキャプチャできます。同時に、この関数の呼び出しスタックを出力することもできます。キャプチャ後、効果的に実行できます。例:
process.on('uncaughtException', function (err) { //打印出错误 console.log(err); //打印出错误的调用栈方便调试 console.log(err.stack); });
これはノード プロセス内での保護と同じですが、多くの人がこの方法を支持していません。つまり、ノードの例外を完全には制御できません。 .JS。
コールバックの前に 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 の機能が 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 + '
それでは、コールバックで生成されないエラーについてはどうすればよいでしょうか?心配しないでください。実際、そのようなノード プログラムはまったく起動できません。
さらに、ノード自身のクラスターにも一定のフォールト トレランスがあります。nginx のワーカーとよく似ていますが、リソース (メモリ) の消費が若干多く、プログラミングはあまり便利ではありません。私たちの JS はこの設計を採用していません。
ノードを使用してノードを保護する
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
rrreee
エラーログも非常に簡単です。プロセスコンソールに直接入力して出力するだけです。エラーを error.log ファイルに記録します: 2>> $WEB_DIR/error.log この行の 2 はエラーを表します。
推奨学習:
以上がNodeJS サービスが常にクラッシュする問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。