系统级文件描述符上限应读/proc/sys/fs/file-max,该值为内核实时运行值;当前用量看/proc/sys/fs/file-nr第一列,若接近第三列(即file-max)则系统吃紧;进程级限制须查/proc/[pid]/limits,ulimit -n仅限当前shell且对systemd服务无效。

看系统级上限:直接读 /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 第一列
/proc/sys/fs/file-nr 输出三列,例如 12480 0 2097152:
- 第一列:已分配的文件描述符总数(含已关闭但尚未回收的)
- 第二列:已分配但未使用的数量(现代内核基本恒为 0)
- 第三列:等于
file-max,即系统硬上限
真正反映系统是否吃紧的是第一列是否持续接近第三列。差值小于 5% 就该预警;如果第一列长期 >95% 的第三列,新进程可能连 fork() 都失败,此时调单个进程的 ulimit 没用。
看进程级限制:必须查 /proc/[pid]/limits
ulimit -n 只显示当前 shell 的软限制,对 systemd 启动的服务完全无效。验证某个服务(比如 Nginx)是否真拿到了高限制,唯一可靠方式是:
- 先拿到 PID:
pgrep nginx | head -n1 - 再查限制:
cat /proc/$(pgrep nginx | head -n1)/limits | grep "Max open files"
输出类似 Max open files 65535 65535 files 才算生效。如果还是 1024 4096,说明 LimitNOFILE=65535 没写进对应 .service 文件的 [Service] 段,或没执行 systemctl daemon-reload。
别被 lsof | wc -l 和 ulimit 带偏
这两个命令最容易误导人:
-
lsof | wc -l权限不足会中断统计,且包含大量无效条目(如已关闭 socket 的残留记录) -
ulimit -n对已运行进程无效,也管不了 systemd 服务——它只影响当前 shell 及其子进程 - 容器场景下,Docker 默认不继承宿主机
ulimit,必须显式加--ulimit nofile=65536:65536
最终生效点永远在 /proc/[pid]/limits 里,那里才是内核实际 enforce 的地方。其他所有配置,无论写在哪、改了几次,没落到这一行,就等于没改。











