Node.jsを実行しているサイトへのトラフィックを非常に最近受け取りました。トラフィックの増加に伴い、これまでになかった多くのクラッシュが始まりました。ログに次のエラーが記録されます。
{ [Error: connect EMFILE] code: 'EMFILE', errno: 'EMFILE', syscall: 'connect' }
Error: connect EMFILE
at errnoException (net.js:670:11)
at connect (net.js:548:19)
at net.js:607:9
at Array.0 (dns.js:88:18)
at EventEmitter._tickCallback (node.js:192:40)
クラッシュする理由を知っている人はいますか?そして、それを解決する方法のアイデア?
Express.jsとSocket.ioを使用しています。 Ubuntuで実行されます。
EMFILE
エラーは、OSがプログラムにより多くのファイル/ソケットを開くことを拒否していることを意味します。
EMFILE
はerror maximum files
を意味します。これは、OSがプログラムにより多くのファイル記述子を開くことを拒否していることを示します。
システムで開いているファイルには、すべてのプロセスによって開かれたディスクファイル、名前付きパイプ、ネットワークソケット、およびデバイスが含まれます。
オペレーティングシステムは、プロセスごとに開くファイルの制限を指定します。
システムのオープンファイル制限を確認するには、ulimit -a
コマンドを使用します。通常、Unixのようなシステムでは、デフォルトは1024です。
制限が1024の場合、ユーザー/プロセスは最大1024ファイルを開くことができます。この制限を超えると、open
、pipe
、およびdup
システムコールが失敗し、EMFILEエラーが発生します。
EMFILE
を取得すると、ほとんどの場合、コードのリークを示しています。 ulimitを高い値に増やすことは、プログラムにリークがある場合の良い解決策ではありません。
漏れの原因を突き止めてください。以下は、オペレーティングシステムのようなUNIXでのデバッグに使用できます。
lsof
意味list open files
コマンドは、開いているファイルのリストを提供します。 nodeJSプログラムにリークが発生していると仮定して、プログラムによって開かれたファイル記述子の総数を確認します。
lsof | grep node | wc -l
ソケットのファイル記述子を見つけるには、次を使用します。
lsof -n -i -P | grep node
これを使用して、リークの場所を特定し、修正することができます。
私の場合、すでにulimitが設定されており、kern.maxfilesの構成はMacで可能な最高の値になっています。
それを修正したのは、最大ソケット数をグローバルに制限することでした。ノードの以降のバージョンでは、制限は無限大です。
次のコード行を追加してみてください。
var https = require('https');
var http = require('http');
https.globalAgent.maxSockets = 5;
http.globalAgent.maxSockets = 5;
要求ライブラリを使用する場合、これらの設定を構成できます。
参照: https://github.com/request/request#request---simplified-http-client
MaxSocketsの詳細: https://nodejs.org/api/http.html#http_agent_maxsockets