要想在 Linux 中成功提高系统最大文件句柄数,fs.file-max、nofile 软硬限制以及 LimitNOFILE 这三处必须同时调高,并且要保证 ulimit -Sn 不能大于 ulimit -Hn;limits.conf 需要同时配置 soft 和 hard 两行,还要确认 pam_limits.so 已正确加载;如果是 systemd 管理的服务,还必须单独设置 LimitNOFILE。只要任意一个环节缺失,系统就很容易报出“Too many open files”错误。

仅执行 ulimit -n 并不能真正修改 Linux 系统的最大文件句柄数,它只会影响当前 shell 及其子进程;想要彻底生效,必须同步调整三个关键位置:fs.file-max(系统级文件句柄总量)、nofile 软硬限制(用户级单进程打开文件数上限)、LimitNOFILE(systemd 服务的独立限制)。少改任何一项,依然可能持续出现 Too many open files 报错。
为什么 ulimit -n 65535 设置后还是 1024
这通常不是命令写错,而是因为软限制受硬限制约束。普通用户执行 ulimit -Sn 65535 时,如果 ulimit -Hn 显示为 4096 或更低,那么该设置会被直接限制住——因为软限制永远不能超过硬限制。
- 临时验证方法:先执行
ulimit -Hn,如果结果 ≤ 4096,那么ulimit -Sn 65535一定不会真正生效 - 临时提升硬限制(仅当前会话有效):
sudo ulimit -Hn 65535,但需要注意,新的硬限制不会自动被所有子进程完整继承 - 想永久生效,必须修改
/etc/security/limits.conf并重新登录系统:例如断开 SSH 后重新连接,或在图形界面退出再登录,而不是只新开一个终端窗口 /etc/security/limits.conf必须同时写入两行配置,并使用空格分隔(不要用 Tab):* soft nofile 65535和* hard nofile 65535
/etc/security/limits.conf 配了却没生效的常见原因
如果已经写入配置,但执行 ulimit -n 仍然显示 1024,那么大多数情况下是 PAM 没有加载限制模块,或者配置顺序被其他规则覆盖了。
- 检查
/etc/pam.d/common-session(Debian/Ubuntu)或/etc/pam.d/system-auth(RHEL/CentOS),确认存在未注释配置:session required pam_limits.so - 不要随意混用通配符和具体用户名:例如
*与www-data同时存在时,PAM 通常按文件顺序匹配第一个规则,后面的配置可能不会生效 - 确认进程确实是以目标用户身份运行:
ps -o pid,uid,comm -u $(whoami),避免误以为是当前用户,实际上却是 root 或其他账号启动的进程
systemd 服务的 LimitNOFILE 必须单独设
/etc/security/limits.conf 对通过 systemctl start 启动的 systemd 服务是无效的,因为 systemd 管理的服务并不经过 PAM 登录流程。
- 让单个服务生效:编辑对应的 unit 文件,例如
/etc/systemd/system/nginx.service,然后在[Service]段中加入:LimitNOFILE=65535 - 全局设置(作用于所有新启动的 service):修改
/etc/systemd/system.conf,并在[Manager]段中加入:DefaultLimitNOFILE=65535 - 修改完成后必须执行:
sudo systemctl daemon-reload,然后再运行sudo systemctl restart nginx - 验证是否生效:
systemctl show nginx | grep LimitNOFILE或cat /proc/$(pgrep nginx)/limits | grep "Max open files"
fs.file-max 必须同步调高,否则系统总池会先耗尽
即使单个进程已经能打开 65535 个文件句柄,如果 /proc/sys/fs/file-max 设置过小(例如默认只有 32768),当多个进程同时占用文件描述符时,系统级文件句柄总池仍会先被耗尽,最终一样会触发错误。
- 查看当前系统值:
cat /proc/sys/fs/file-max - 临时修改并立即生效:
sudo sysctl -w fs.file-max=1048576 - 永久生效方式:在
/etc/sysctl.conf中追加fs.file-max = 1048576,随后执行sudo sysctl -p - 不要设置得过高——如果超过 200 万,可能会增加内核内存压力;通常 100 万已经足够支撑上千并发的 HTTP 服务
- 建议顺便查看当前使用情况:
cat /proc/sys/fs/file-nr,输出共有三列,其中第三列表示file-max,第二列表示当前已使用数量
很多人在排查 Linux “打开文件过多”问题时,最容易忽略的一点就是:systemd 服务根本不会读取 limits.conf。此外,也有人只调整了 ulimit 就以为设置完成,或者只改了 soft 限制却漏掉 hard 限制,又或者只处理了用户级限制,却没有同步提高 fs.file-max。以上这些关键点中,只要有一个没有处理到位,Too many open files 错误依旧会反复出现。
