Mir*_* N. 26 java linux jetty file-descriptor ioexception
我正在尝试在Linux上的Jetty 7.0.1中运行的Java webapp中调试文件描述符泄漏.
由于打开的文件过多而导致请求开始失败,应用程序已经愉快地运行了一个月左右,并且必须重新启动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)
Run Code Online (Sandbox Code Playgroud)
起初我认为问题在于启动外部程序的代码,但它使用的是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"));
}
}
Run Code Online (Sandbox Code Playgroud)
在服务器上列出打开的文件我可以看到大量的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
Run Code Online (Sandbox Code Playgroud)
当Jetty开始时,只有10个FIFO,几天之后就有数百个.
我知道在这个阶段有点模糊,但你有什么建议在下一步看,或者如何获得有关这些文件描述符的更详细的信息?
ofa*_*vre 24
问题来自您的Java应用程序(或您正在使用的库).
首先,您应该阅读整个输出(Google for StreamGobbler)和pronto!
Javadoc说:
父进程使用这些流向子进程提供输入并从子进程获取输出.由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞甚至死锁.
其次,waitFor()您的流程终止.然后,您应该关闭输入,输出和错误流.
最后 destroy()你的过程.
我的来源:
当你在Linux上运行时,我怀疑你的文件描述符已经用完了.查看ulimit.这篇文章描述了这个问题:http://www.cyberciti.biz/faq/linux-increase-the-maximum-number-of-open-files/
小智 5
除了查看文件泄漏等根本原因问题,以便合法地增加"打开文件"限制并在重新启动时保持这种限制,请考虑编辑
/etc/security/limits.conf
Run Code Online (Sandbox Code Playgroud)
通过添加这样的东西
jetty soft nofile 2048
jetty hard nofile 4096
Run Code Online (Sandbox Code Playgroud)
其中"jetty"是这种情况下的用户名.有关limits.conf的更多详细信息,请参阅http://linux.die.net/man/5/limits.conf
注销然后再次登录并运行
ulimit -n
Run Code Online (Sandbox Code Playgroud)
验证更改是否已发生.此用户的新流程现在应该符合此更改.此链接似乎描述了如何对已经运行的进程应用限制,但我还没有尝试过.
对于大型Java应用程序,默认限制1024可能太低.
| 归档时间: |
|
| 查看次数: |
91066 次 |
| 最近记录: |