一尘不染

打开文件错误太多,但lsof显示合法数量的打开文件

linux

我的Java程序失败了

Caused by: java.io.IOException: Too many open files
        at java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.io.File.createNewFile(File.java:883)...

这是来自的关键行/etc/security/limits.conf。他们将用户的最大文件数设置为500k:

root                     soft    nofile          500000
root                     hard    nofile          500000
*                        soft    nofile          500000
*                        hard    nofile          500000

我跑去lsof统计打开的文件数-
包括全局和jvm进程。我检查了中的柜台/proc/sys/fs。一切似乎还可以。我的进程仅打开了4301个文件,限制为500k:

:~# lsof | wc -l
5526
:~# lsof -uusername | wc -l
4301
:~# cat /proc/sys/fs/file-max
744363
:~# cat /proc/sys/fs/file-max
744363
:~# cat /proc/sys/fs/file-nr
4736    0       744363

这是Ubuntu 11.04服务器。我什至已经重新启动,所以我很肯定正在使用这些参数。

我不知道它是否相关,但是该过程由upstart脚本启动,该脚本使用setuidgid启动该过程,如下所示:

exec setuidgid username java $JAVA_OPTS -jar myprogram.jar

我缺少什么?


阅读 479

收藏
2020-06-07

共1个答案

一尘不染

事实证明,问题在于我的程序正在作为新贵的初始化脚本运行,并且该exec节未调用shell。ulimitlimits.conf中的设置仅适用于Shell中的用户进程。

我通过将exec节更改为

exec sudo -u username java $JAVA_OPTS -jar program.jar

它在用户名的默认外壳中运行java。这使程序可以使用所需数量的打开文件。

已经看到它提到您也可以ulimit -n在调用命令之前先进行调用。对于新贵的脚本,我认为您应该改用script节。

我发现了一个更好的诊断比lsofls /proc/{pid}/fd | wc -l,获得打开的文件描述符的精确计数。通过监视,我可以看到失败是在4096个打开的fds处发生的。我不知道4096的来源。它不在/
etc中的任何地方;我猜它已经编译进内核了。

2020-06-07