質問

Linux 上の Jetty 7.0.1 で実行されている Java Web アプリでのファイル記述子のリークをデバッグしようとしています。

アプリは 1 か月ほど問題なく実行されていましたが、次の理由でリクエストが失敗し始めました。 開いているファイルが多すぎます, 、Jettyを再起動する必要がありました。

java.io.IOException: Cannot run program [external program]: java.io.IOException: error=24, Too many open files
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)
    at java.lang.Runtime.exec(Runtime.java:593)
    at org.apache.commons.exec.launcher.Java13CommandLauncher.exec(Java13CommandLauncher.java:58)
    at org.apache.commons.exec.DefaultExecutor.launch(DefaultExecutor.java:246)

最初は、外部プログラムを起動するコードに問題があるのではないかと思いましたが、 コモンズエグゼクティブ それに何も問題はありません:

CommandLine command = new CommandLine("/path/to/command")
    .addArgument("...");
ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream();
Executor executor = new DefaultExecutor();
executor.setWatchdog(new ExecuteWatchdog(PROCESS_TIMEOUT));
executor.setStreamHandler(new PumpStreamHandler(null, errorBuffer));
try {
    executor.execute(command);
} catch (ExecuteException executeException) {
    if (executeException.getExitValue() == EXIT_CODE_TIMEOUT) {
        throw new MyCommandException("timeout");
    } else {
        throw new MyCommandException(errorBuffer.toString("UTF-8"));
    }
}

サーバー上で開いているファイルをリストすると、多数の FIFO があることがわかります。

# lsof -u jetty
...
java    524 jetty  218w  FIFO        0,6      0t0 19404236 pipe
java    524 jetty  219r  FIFO        0,6      0t0 19404008 pipe
java    524 jetty  220r  FIFO        0,6      0t0 19404237 pipe
java    524 jetty  222r  FIFO        0,6      0t0 19404238 pipe

Jetty が起動したとき、FIFO はわずか 10 個でしたが、数日後には数百個になりました。

この段階では少し曖昧だとは思いますが、次にどこを調べればよいか、またはそれらのファイル記述子に関するより詳細な情報を取得する方法について何か提案はありますか?

役に立ちましたか?

解決

あなたの外部プログラムが正常に動作しません。それはそれをしない理由を見てみましょう。

他のヒント

問題は Java アプリケーション (または使用しているライブラリ) に起因します。

初め, 、出力全体 (StreamGobbler については Google) を読んでください。

Javadoc 言います:

親プロセスは、これらのストリームを使用して、サブプロセスから入力をフィードし、出力を取得します。一部のネイティブプラットフォームは、標準の入力ストリームと出力ストリームに限られたバッファサイズのみを提供するため、入力ストリームを迅速に書き込んだり、サブプロセスの出力ストリームを読み取ったりしないと、サブプロセスがブロックされたり、デッドロックさえしたりする可能性があります。

第二に, waitFor() プロセスを終了します。次に、入力、出力、およびエラー ストリームを閉じる必要があります。

ついに destroy() あなたのプロセス。

私の情報源:

あなたがLinux上で実行されているとおり、

私はあなたのファイル記述子が不足している疑いがあります。 ulimitのをチェックしてください。 ます。http:ここでは、問題を説明する記事です://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/する

は、あなたのアプリの本質を知らないが、私はこのエラーが原因で接続プールリークの複数回現れ、そのためにはチェックアウトする価値があるだろう見てきました。 Linuxでは、ソケット接続は、ファイル記述子だけでなく、ファイル・システムのファイルを消費します。ただ、考えています。

ほかに「開いているファイル」の制限を正当な増加を行うと、編集を検討し、リブート後その持っているために、ファイル等の漏洩、などの根本的な原因の問題を検討してから

/etc/security/limits.conf

このような何かを追加することにより、

jetty soft nofile 2048
jetty hard nofile 4096

ここで、「桟橋」は、この場合のユーザ名です。 limits.confをの詳細については、 http://linux.die.net/manを見ます/5/limits.confする

ログオフし、再度ログインして、実行します。

ulimit -n

変更が行われたことを確認します。このユーザーによる新しいプロセスが今、この変更に従うべきです。 このリンクには、すでに実行中のプロセスに制限を適用する方法を説明しているようだが、私それを試していません。

デフォルトの制限値1024は、大規模なJavaアプリケーションのための低すぎることができます。

あなたはFDSを自分で処理することができます。 JavaでExecは、プロセスオブジェクトを返します。プロセスがまだ実行されている場合は断続的に確認してください。それが近いプロセスSTDERR、STDINおよびSTDOUTストリームを完了すると(例えばproc.getErrorStream.close())。それは漏れを軽減します。

あなたは、同時に多くのファイルにデータを書き込んでいる場合、この問題が来ると、あなたのオペレーティングシステムは、オープンファイルの一定の制限があります。 Linuxでは、あなたは、開いているファイルの上限を増やすことができます。

https://www.tecmint.com/増加・セットのオープンファイルの制限インのlinux /

私は変更するにはどうすればよいです開いているファイルの数は、Linuxに制限ですか

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top