如何调整 Linux 内核参数 file-max 解决打开文件数过多报错?

文章导读
调整 fs.file-max 能解决系统级文件句柄耗尽问题,但多数报错其实源于单进程限制,需同时检查 ulimit 设置。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

调整 fs.file-max 能解决系统级文件句柄耗尽问题,但多数报错其实源于单进程限制,需同时检查 ulimit 设置。

先说结论:调整内核参数只是其中一环,务必区分系统总量限制与单进程限制。

  • 先确认:区分是系统级 ENFILE 还是进程级 EMFILE 报错
  • 先处理:同时修改 sysctl 配置与 limits 配置
  • 再验证:观察 file-nr 变化并重启相关服务

命令速用版

临时生效(重启失效):

sysctl -w fs.file-max=2097152

永久生效:

echo "fs.file-max=2097152" >> /etc/sysctl.conf
sysctl -p

为什么会这样

Linux 内核将打开的文件视为系统资源。file-max 代表整个系统能打开的文件句柄总数,而每个进程还有自己的限制(ulimit)。当系统总占用达到 file-max,或单个进程占用达到 ulimit 限制时,都会报“打开文件数过多”。

分步处理

1. 查看当前系统限制与使用情况:

cat /proc/sys/fs/file-max
cat /proc/sys/fs/file-nr

file-nr 的三个数字分别代表已分配、已分配但未释放、最大限制。如果第一个数字接近第三个,说明系统级限制到了。

2. 修改内核参数:

编辑 /etc/sysctl.conf 或 /etc/sysctl.d/99-custom.conf,添加:

如何调整 Linux 内核参数 file-max 解决打开文件数过多报错?
fs.file-max=2097152

执行 sysctl -p 使配置生效。

3. 修改单进程限制(关键):

编辑 /etc/security/limits.conf,添加:

* soft nofile 65535
* hard nofile 65535

注意:某些服务需要在 systemd 单元文件中单独配置 LimitNOFILE。

怎么验证是否生效

再次执行 cat /proc/sys/fs/file-nr,观察第一个数字是否不再卡在最大值附近。对于进程限制,在新登录的会话中执行 ulimit -n 查看。

常见坑

1. 只改 file-max 不改 ulimit:大部分应用报错是因为单进程限制,而非系统总量。

2. 修改后未重启服务:已运行的进程不会自动继承新的 ulimit 限制,需重启服务或重新登录。

3. 忽视文件泄漏:如果文件数持续上涨不回落,可能是程序未关闭文件句柄,调大限制只是延缓问题。

参考来源

  • The Linux Kernel Documentation - fs.txt: https://www.kernel.org/doc/html/latest/admin-guide/sysctl/fs.html
  • Linux man-pages - proc(5): https://man7.org/linux/man-pages/man5/proc.5.html
  • Linux man-pages - sysctl(8): https://man7.org/linux/man-pages/man8/sysctl.8.html