/proc/sys/fs/file-max 是内核实际生效的系统级文件描述符总数上限;/proc/sys/fs/file-nr 第一列是已分配fd总数,接近第三列(file-max)时需预警;查进程限制应看 /proc/[pid]/limits,而非 ulimit;fs.nr_open 是单进程硬上限,默认1048576,须与 file-max 协调调整。

查系统总上限:直接读 /proc/sys/fs/file-max
这个值是内核当前实际生效的系统级文件描述符总数上限,不是配置文件里写的、也不是缓存值。执行 cat /proc/sys/fs/file-max 得到的数字,就是所有进程加起来最多能用多少个 FD。别信 sysctl fs.file-max 的输出——某些发行版(如 RHEL 8+)用 systemd-sysctl 管理,sysctl 显示的是加载缓存值,而 /proc/sys/fs/file-max 是实时运行值。
查当前已用数量:盯紧 /proc/sys/fs/file-nr 第一列
cat /proc/sys/fs/file-nr 输出三列,例如 12480 0 2097152:
- 第一列(12480):已分配出去的 fd 总数(含已关闭但尚未回收的)
- 第二列(0):已分配但未使用的 fd 数,现代内核基本恒为 0,可忽略
- 第三列(2097152):等于
file-max,即系统硬上限
真正关键的是第一列是否接近第三列。差值小于 10% 就该预警了——此时再开新进程或新连接会直接失败,调单个进程的 ulimit -n 没用。
查某进程的实际限制:看 /proc/[pid]/limits
这是唯一能确认“这个进程到底被卡在哪”的地方。比如查 nginx 主进程:
- 先找 PID:
pgrep nginx | head -n1 - 再查限制:
cat /proc/$(pgrep nginx | head -n1)/limits | grep "Max open files"
输出类似 Max open files 1024 4096 files,左边是软限制(实际生效值),右边是硬限制(上限)。注意:ulimit -n 只影响当前 shell 启动的进程;systemd 服务必须在 .service 文件里写 LimitNOFILE,否则 /etc/security/limits.conf 对它无效。
查当前 shell 的限制:用 ulimit -n、ulimit -Hn、ulimit -Sn
这三个命令分别返回:
-
ulimit -n:软限制(等价于ulimit -Sn) -
ulimit -Hn:硬限制(root 或 CAP_SYS_RESOURCE 才能调高) -
ulimit -Sn:软限制(进程实际能用的上限,不能超过硬限制)
但要注意:这些只对当前 shell 及其子进程有效。已运行的服务(如通过 systemctl start nginx 启动的)完全不继承这个值,必须单独验证其 /proc/[pid]/limits。
最易被忽略的一点:fs.nr_open 是单进程硬上限,默认 1048576。如果你把 file-max 设成 2097152,但没同步调高 fs.nr_open,那新进程仍会被截断——哪怕 /proc/[pid]/limits 显示软硬限都够大,open() 还是会失败。











