“Too many open files”错误需五层协同调优:内核fs.file-max、用户limits.conf(含PAM启用)、systemd服务LimitNOFILE、Nginx的worker_rlimit_nofile与worker_connections,以及soft/hard nofile限制,缺一不可。

直接调高 ulimit 的 nofile 值是解决“Too many open files”错误最常见也最关键的一步,但必须分层操作——只改当前 shell 无效,只改 limits.conf 对 systemd 服务也不起作用。核心在于理清 soft/hard 限制、会话级、用户级、服务级和内核级这五层控制关系。
看清当前限制值
先确认问题所在,再动手修改:
- ulimit -n:显示当前会话的 soft nofile(实际生效值)
- ulimit -Sn && ulimit -Hn:分别查软限和硬限,若软限无法提升,说明硬限卡住了
- cat /proc/sys/fs/file-max:系统全局最大文件描述符总数,所有进程共用
- ls /proc/$(pidof your_service)/fd | wc -l:查看某服务真实已打开的 fd 数量
临时调高(快速验证用)
适合调试或单次运行高并发程序,退出终端即失效:
- 提升 soft 限制(需 ≤ 当前 hard 值):ulimit -n 65535
- 若报 “Operation not permitted”,先提 hard 限(需 root):sudo ulimit -Hn 65535,再执行上一条
- 验证:ulimit -n 应返回 65535
永久生效(用户登录级)
让指定用户每次登录都自动加载新限制,适用于普通服务用户(如 www-data、redis):
- 编辑 /etc/security/limits.conf,追加(注意空格,不是 tab):
www-data soft nofile 65535
www-data hard nofile 65535 - 或对所有非 root 用户统一设限:
* soft nofile 65535
* hard nofile 65535 - 确保 PAM 加载生效:检查 /etc/pam.d/common-session 是否含 session required pam_limits.so
- 修改后需重新登录或 su - www-data 切换用户再验证
适配 systemd 服务(关键!常被忽略)
nginx、redis、java 应用等由 systemd 托管的服务完全不读 limits.conf,必须单独配置:
- 创建覆盖配置:sudo systemctl edit nginx.service
- 写入:
[Service]
LimitNOFILE=65535 - 重载并重启:sudo systemctl daemon-reload && sudo systemctl restart nginx
- 验证:systemctl show nginx | grep LimitNOFILE 或 cat /proc/$(pidof nginx)/limits | grep "Max open files"
补充内核级总上限(高并发必备)
当并发连接数超 10 万时,仅调进程限制不够,还需提升系统总容量:
- 临时生效:sudo sysctl -w fs.file-max=2097152
- 永久生效:在 /etc/sysctl.conf 中添加一行:
fs.file-max = 2097152 - 执行 sudo sysctl -p 加载


















