必须同时调整用户级ulimit、系统级fs.file-max和systemd级LimitNOFILE,且分别通过重登录、sysctl -p和systemctl daemon-reload生效,缺一不可。

改了 ulimit -n 却还是报 Too many open files,不是命令没输对,而是只调了软限制、没碰硬限制,也没动系统总池和 systemd 服务配置——这四个点漏掉任何一个,都白改。
ulimit -n 为什么设不上去
执行 ulimit -Sn 65535 失败或静默截断,大概率是硬限制卡住了。普通用户不能突破硬限制,而硬限制由 PAM 在登录时加载,ulimit -n 命令本身无法抬高它。
- 先查硬限制:
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 服务的句柄数根本不受 limits.conf 控制
/etc/security/limits.conf 对 systemctl start 启的服务完全无效,因为 systemd 不走 PAM 登录流程。
- 单个服务(如 nginx):编辑
/etc/systemd/system/nginx.service,在[Service]段下加:LimitNOFILE=65535 - 全局生效:改
/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 万可能引发内核内存压力;顺手检查使用量:
cat /proc/sys/fs/file-nr,第三列是上限,第二列是已用数
真正要防 Too many open files,得同时调 ulimit -n(用户级)、fs.file-max(系统级)、LimitNOFILE(systemd 级)——三者缺一不可,而且每一步的生效条件都不一样,容易漏掉重登、重载、重读这些动作。


















