私の経験から、PHPサーバーはログまたはサーバーエンドに例外をスローしますが、node.jsは単にクラッシュします。すべてが非同期に行われるため、コードをtry-catchで囲むことも機能しません。運用サーバーで他の全員が何をしているのか知りたいです。
http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception でNode自身のドキュメントを読むことができるため、他の回答は本当に正気ではありません。
誰かが他の記載された回答を使用している場合は、Nodeドキュメントを読んでください:
uncaughtException
は例外処理の非常に粗雑なメカニズムであり、将来削除される可能性があることに注意してください。
PM2
まず、PM2
のNode.js
をインストールすることを強くお勧めします。 PM2は、クラッシュの処理とNodeアプリの監視、および負荷分散に非常に優れています。 PM2は、クラッシュした場合、何らかの理由で停止した場合、またはサーバーが再起動した場合でも、Nodeアプリをすぐに開始します。そのため、コードを管理した後でもアプリがクラッシュした場合、PM2はすぐに再起動できます。詳細については、 PM2のインストールと実行
アプリ自体のクラッシュを防ぐためのソリューションに戻りましょう。
そのため、最後にNodeドキュメント自体が示唆するものを思いつきました。
uncaughtException
を使用せず、代わりにdomains
とともにcluster
を使用してください。uncaughtException
を使用する場合は、未処理の例外が発生するたびにアプリケーションを再起動してください!
ドメインwithCluster
実際に行うことは、エラーをトリガーしたリクエストにエラー応答を送信し、他のユーザーを通常の時間で終了させ、そのワーカーでの新しいリクエストのリッスンを停止することです。
このように、マスタープロセスはエラーが発生したときに新しいワーカーをフォークできるため、ドメインの使用はクラスターモジュールと連動します。以下のコードを参照して、私が意味することを理解してください
Domain
を使用し、Cluster
を使用してプログラムを複数のワーカープロセスに分離する復元力を使用することにより、より適切に対応し、エラーをより安全に処理できます。
var cluster = require('cluster');
var PORT = +process.env.PORT || 1337;
if(cluster.isMaster)
{
cluster.fork();
cluster.fork();
cluster.on('disconnect', function(worker)
{
console.error('disconnect!');
cluster.fork();
});
}
else
{
var domain = require('domain');
var server = require('http').createServer(function(req, res)
{
var d = domain.create();
d.on('error', function(er)
{
//something unexpected occurred
console.error('error', er.stack);
try
{
//make sure we close down within 30 seconds
var killtimer = setTimeout(function()
{
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
//stop taking new requests.
server.close();
//Let the master know we're dead. This will trigger a
//'disconnect' in the cluster master, and then it will fork
//a new worker.
cluster.worker.disconnect();
//send an error to the request that triggered the problem
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
}
catch (er2)
{
//oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
//Because req and res were created before this domain existed,
//we need to explicitly add them.
d.add(req);
d.add(res);
//Now run the handler function in the domain.
d.run(function()
{
//You'd put your fancy application logic here.
handleRequest(req, res);
});
});
server.listen(PORT);
}
Domain
は廃止予定であり、ノードのドキュメントに記載されているように新しい代替品が提供されると削除されます
このモジュールは廃止予定です。置換APIが完成すると、このモジュールは完全に非推奨になります。ドメインが提供する機能を絶対に必要とするユーザーは、当分の間それに依存する可能性がありますが、将来は別のソリューションに移行する必要があります。
ただし、新しい置換が導入されない限り、Node Documentationが示唆している唯一の優れたソリューションは、ドメインのあるクラスターです。
Domain
およびCluster
を深く理解するには
https://nodejs.org/api/domain.html#domain_domain (Stability: 0 - Deprecated
)
https://nodejs.org/api/cluster.html
@Stanley Luoに、クラスタとドメインに関するこのすばらしい詳細な説明を共有してくれてありがとう
私はこのコードをrequireステートメントとグローバル宣言のすぐ下に置きました。
process.on('uncaughtException', function (err) {
console.error(err);
console.log("Node NOT Exiting...");
});
私のために働く。私がそれについて気に入らない唯一のことは、私がただ物事をクラッシュさせたならば、私がそうするほど多くの情報を得ないことです。
前述のとおり、 hereerror.stack
は、エラーの原因となった行番号など、より完全なエラーメッセージを提供します。
process.on('uncaughtException', function (error) {
console.log(error.stack);
});
supervisor
を試してください
npm install supervisor
supervisor app.js
または、代わりに forever
をインストールできます。
これにより、サーバーが再起動してクラッシュした場合にサーバーを回復できます。
forever
をコード内で使用して、クラッシュしたプロセスを適切に回復できます。
forever
ドキュメントには、プログラムによる終了/エラー処理に関する確固たる情報があります。
Try-catchを使用すると、キャッチされなかったエラーを解決できますが、一部の複雑な状況では、非同期関数をキャッチするなどの仕事を正しく行いません。 Nodeでは、非同期関数呼び出しにアプリのクラッシュ操作が含まれている可能性があることに注意してください。
uncaughtException
を使用することは回避策ですが、非効率的であると認識されており、Nodeの将来のバージョンでは削除される可能性が高いため、期待しないでください。
理想的な解決策は、ドメインを使用することです: http://nodejs.org/api/domain.html
サーバーがクラッシュした場合でもアプリが稼働していることを確認するには、次の手順を使用します。
ノードクラスターを使用して、コアごとに複数のプロセスを分岐します。そのため、1つのプロセスが停止した場合、別のプロセスが自動起動します。チェックアウト: http://nodejs.org/api/cluster.html
try-catchまたはuncaughtを使用する代わりに、ドメインを使用して非同期操作をキャッチします。トライキャッチやキャッチが悪い考えだと言っているのではありません!
forever/supervisorを使用してサービスを監視する
デーモンを追加してノードアプリを実行します: http://upstart.ubuntu.com
お役に立てれば!
Pm2ノードモジュールを試してみてください。かなり一貫性があり、素晴らしいドキュメントがあります。ロードバランサーが組み込まれたNode.jsアプリのプロダクションプロセスマネージャー。この問題についてはuncaughtExceptionを避けてください。 https://github.com/Unitech/pm2
Restifyで素晴らしい動作:
server.on('uncaughtException', function (req, res, route, err) {
log.info('******* Begin Error *******\n%s\n*******\n%s\n******* End Error *******', route, err.stack);
if (!res.headersSent) {
return res.send(500, {ok: false});
}
res.write('\n');
res.end();
});
UncaughtExceptionは「非常に粗雑なメカニズム」で(真)、ドメインは非推奨になりました。ただし、(論理)ドメイン周辺のエラーをキャッチするためのメカニズムが必要です。図書館:
https://github.com/vacuumlabs/yacol
これを行うのに役立ちます。コードを少し書くだけで、コード全体にニースのドメインセマンティクスを設定できます。