如何设置全局nofile限制以避免“打开文件过多”错误?

31
我有一个 WebSocket 服务。奇怪的是出现了错误:“打开的文件太多”,但我已经设置了系统配置:
/etc/security/limits.conf
*               soft    nofile          65000
*               hard    nofile          65000

/etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65000

ulimit -n
//output 6500

所以我认为我的系统配置是正确的。

我的服务由supervisor管理,supervisor可能有限制吗?

检查由supervisor启动的进程:

cat /proc/815/limits
Max open files            1024                 4096                 files 

检查流程手动启动:

cat /proc/900/limits
Max open files            65000                 65000                 files 

原因是使用supervisor管理服务。如果我重启supervisor并重启子进程,在重新启动系统之前“最大打开文件数”为65000,但在系统自动启动supervisor后为1024。

可能是supervisor的启动级别太高,当supervisor启动时系统配置不起作用?

编辑:

系统:Ubuntu 12.04 64位

这不是supervisor的问题,所有在系统重新启动后自动启动的进程都不使用系统配置(最大打开文件数=1024),但重新启动可以解决问题。

更新:

可能的问题是:

现在的问题是如何设置全局nofile限制,因为我不想在每个upstart脚本中都设置nofile限制。


1
如果你不想在每个upstart脚本中设置limit nofile,请尝试在/etc/sysctl.conf中设置fs.file-max - jfs
10个回答

13

通过在文件中为所有用户设置限制解决了这个问题:

$ cat /etc/security/limits.d/custom.conf
* hard nofile 550000
* soft nofile 550000

在设置限制之后,重新启动服务器。

非常重要: /etc/security/limits.d/文件夹包含用户特定的限制。在我的情况下,它包含与Hadoop 2(Cloudera)相关的限制。这些用户特定的限制将覆盖全局限制,因此如果未应用您的限制,请务必检查文件夹/etc/security/limits.d/和文件/etc/security/limits.conf中的用户特定限制。

注意: 在所有情况下,都应该设置用户特定限制。应避免设置全局(*)限制。在我的情况下,这是一个隔离的环境,只需要消除实验中的文件限制问题。

希望这可以帮助某个人节省一些时间 - 因为我花了太多时间拔自己的头发!


9

我曾经遇到过同样的问题。虽然运行ulimit -Sn显示我的新限制,但运行supervisorctl restart all和查看进程文件并没有显示新的限制。

问题在于supervisord仍然具有原始限制。因此,它创建的任何子进程仍然具有原始限制。

因此,解决方法是杀死并重新启动supervisord


2
非常感谢您。您解决了我的问题。我花了将近两个小时来弄清楚发生了什么。 - banuj

7
尝试编辑/etc/sysctl.conf,并全局调整限制。例如:强制将文件限制设置为100000。
vi /etc/sysctl.conf

添加:

fs.file-max = 100000

保存并关闭文件。用户需要注销并重新登录才能使更改生效,或者只需输入以下命令:

sysctl -p

5

对于任何疲惫的谷歌用户:您可能在寻找supervisor配置中的minfds设置。此设置似乎对supervisord进程以及其子进程均生效。我尝试了许多其他策略,包括在执行实际程序之前启动设置限制的shell脚本,但这是唯一有效的方法。


默认值为1024,这是最理想的值吗? - Kishan Mehta

3

您可以通过以下方式找到您的限制:

 cat /proc/sys/fs/file-max

或者使用sysctl -a | grep file命令。

可以在/proc/sys/fs/file-max文件中更改,也可以使用以下命令:

sysctl -w fs.file-max=100000

2
您可以通过以下方式设置服务的限制:
/etc/systemd/system/{NameofService}.service文件中添加LimitNOFILE=65536

2
luqmaan的回答对我很有帮助,但是有一个小问题:在Ubuntu中,*通配符不适用于root用户(如limits.conf的注释所述)。
如果以root用户身份启动supervisord,则需要显式设置root用户的限制: vi /etc/security/limits.conf
root soft nofile 65535
root hard nofile 65535

0

对我来说,使用 prlimit --nofile=softlimit:hardlimit 就解决了问题。

关于软限制和硬限制的一些背景知识:

您可以设置软限制和硬限制。系统不允许用户超过其硬限制。但是,系统管理员可以设置一个软限制,用户可以暂时超过该限制。软限制必须小于硬限制。

一旦用户超过软限制,计时器开始计时。当计时器在滴答声时,用户被允许在软限制以上操作,但不能超过硬限制。一旦用户低于软限制,计时器将被重置。但是,如果用户的使用量在计时器到期时仍然高于软限制,则软限制将被强制执行为硬限制。

参考文献:https://docs.oracle.com/cd/E19455-01/805-7229/sysresquotas-1/index.html

在我的情况下,增加软限制就解决了问题。我建议在增加硬限制之前与系统管理员进行沟通。

参考prlimit命令语法这里。 在设置软限制之前,请确保使用以下命令检查系统硬限制: prlimit -n 这是您可以将其设置的最大值。

如果您想要在Linux服务器上永久保留配置,可以像其他人建议的那样编辑/ etc / security / limits.conf。 如果这不起作用(在我的服务器上无法编辑),请在.bashrc中设置它。


0

暂时可以通过以下命令解决:

ulimit -n 2048

其中2048(或您可以根据需要设置)是进程(nproc)的数量。 要进行永久解决方案,需要配置两个文件。 对于CentOS/RHEL 5或6

/etc/security/limits.conf
/etc/security/limits.d/90-nproc.conf

适用于CentOS/RHEL 7

/etc/security/limits.conf
/etc/security/limits.d/20-nproc.conf

在涉及到编程的两个文件中,添加或修改以下行,其中test是一个特定的用户。
test hard nproc 2048
test soft nproc 16384

软限制:用户可以更改,但不能超过硬限制。 硬限制:这是由超级用户设置的软限制上限,并由内核强制执行的限制。


-3

我认为这与已打开的文件无关(这只是错误的错误消息)。您的应用程序使用的任何端口都在使用中。 1. 尝试使用命令查找进程ID

ps aux

2. 用命令结束进程(例如8572)

sudo kill -9 8572

3. 重新启动您的应用程序。


5
不应建议人们使用 kill -9。 - Tommaso Barbugli
1
文件描述符在Unix/Linux中用于任何设备访问。因此,每个打开到进程的网络套接字都使用另一个打开的文件句柄。这就解释了为什么您在常规文件系统文件以及任何设备文件(例如网络连接)的情况下可能会遇到“打开的文件太多”的问题。 - gaoithe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接