注册

Linux报 “maximum number of file descriptors reached” 异常的原因以及解决办法

  1. 原因

Linux系统中,每个进程打开的文件描述符数(File Descriptor,简称FD)有一个限制,这个限制可以通过命令 ulimit -n 查看。当进程打开的 FD 数目达到了系统限制时,新的 FD 将无法被创建,可能会导致系统出现各种问题,例如网络连接无法建立、文件无法打开等。当进程在达到限制之前就消耗完了全部的 FD 资源,系统就会报 maximum number of file descriptors reached 错误。

  1. 解决办法

2.1. 查看和调整文件描述符限制

我们可以通过 ulimit -n 命令来查看当前系统的文件描述符限制。

示例:

ulimit -n

输出:

1024

上面的输出说明该系统的文件描述符限制为1024。调整文件描述符限制可以通过 ulimit -n XXXX 命令来实现,其中 XXXX 为新的限制值。

示例:

ulimit -n 65535

这条命令将文件描述符限制值修改为 65535。

2.2. 使用优化内核参数的方式增加文件描述符限制

如果单个进程需要打开大量的文件,适合使用此方法。可以通过调整 /etc/sysctl.conf 文件的内容,修改内核参数来增加文件描述符限制。

打开 /etc/sysctl.conf 文件,添加或修改以下两行:

fs.file-max = 65535
fs.nr_open = 65535

以上两个参数分别表示系统所能使用的最大文件数量和用户最大文件打开数。用新的参数值替换掉原来的默认值,然后保存并关闭文件。

执行以下命令,使修改生效:

sysctl -p

2.3. 关闭不需要的文件描述符

我们可以通过查看 lsof (List Open Files)命令来定位哪些进程占用了大量的文件描述符,并进行进一步的处理,例如关闭一些不必要的文件描述符。

示例:

# 查看Nginx进程打开了多少文件
lsof -p $(pidof nginx) | wc -l

# 列出Nginx进程打开的所有文件(不包含目录)
lsof -n -p $(pidof nginx) | grep -v '^COMMAND' | grep -v ^\w+/ | awk '{print $NF}' | sort -u

# 结合 xargs 命令,将 Nginx 进程当前打开的文件全部关闭
lsof -n -p $(pidof nginx) | grep -v '^COMMAND' | grep -v ^\w+/ | awk '{print $NF}' | sort -u | xargs -I {} bash -c 'echo {} && exec 1>>/dev/null 2>&1 && exec {}<&-'
  1. 结语

以上介绍了 Linux 中报 maximum number of file descriptors reached 错误的原因以及三种解决办法,其中第一种和第二种是比较常用的方法,视实际情况选择合适的办法即可。