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)
最初は、外部プログラムを起動するコードに問題があると思っていましたが、それはcommons-execを使用しており、問題はありません。
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 個しかありませんが、数日後には数百個になります。
この段階では少し曖昧であることは承知していますが、次にどこを見るべきか、またはこれらのファイル記述子に関する詳細情報を取得する方法について何か提案はありますか?