linux修改最大文件打开数需三层协同:单进程(ulimit/limits.conf)、用户级(pam加载pam_limits.so)、系统级(fs.file-max),缺一不可;systemd服务须单独配置limitnofile,且需验证运行时值。

Linux 系统中修改“最大文件打开数”需分三层处理:单进程限制(nofile)、用户级限制(limits.conf)、系统级总上限(file-max)。三者有依赖关系,缺一不可,否则会出现“改了不生效”或“服务仍报 Too many open files”。
单进程能开多少文件?看 ulimit -n 和 /etc/security/limits.conf
这是最常被调整的部分,决定每个进程最多能打开多少个文件描述符(fd)。
- 软限制(soft limit):实际生效值,进程可自行调高(不超过硬限制)
- 硬限制(hard limit):软限制的天花板,普通用户不能突破,root 可设
操作步骤:
- 编辑
/etc/security/limits.conf:sudo nano /etc/security/limits.conf
在末尾添加(以所有普通用户为例):
- soft nofile 65535
- hard nofile 65535
> ✅ 若只针对某用户(如 `www-data`),把 `*` 换成用户名;部分发行版(如 CentOS)对 `*` 支持不佳,建议显式写用户名。
-
确保 PAM 加载 limits 模块:
检查/etc/pam.d/common-session(Debian/Ubuntu)或/etc/pam.d/login(RHEL/CentOS)中含:session required pam_limits.so
如无,手动添加。
-
必须重新登录用户(或重启服务)才生效。
验证方式:su - username # 切换目标用户 ulimit -n # 应显示 65535
⚠️ 注意:sudo -u user cmd 不触发 PAM 登录流程 → 不继承该限制;systemd 服务默认也不读此文件。
systemd 服务怎么设?必须写进 unit 文件
nginx、redis、Java 应用等由 systemd 托管的服务,无视 limits.conf,需单独配置:
-
创建覆盖配置:
sudo systemctl edit nginx.service
-
写入:
[Service] LimitNOFILE=65535
-
重载并重启:
sudo systemctl daemon-reload sudo systemctl restart nginx
✅ 验证是否生效:
systemctl show -p LimitNOFILE nginx.service # 查看设置值 cat /proc/$(pgrep nginx)/limits | grep "Max open files" # 查运行时实际值
整个系统最多能开多少文件?调 fs.file-max
这是内核级总配额,所有进程共用。若单进程设了 65535,但 file-max 只有 10 万,10 个进程就撞墙。
查看当前值:
cat /proc/sys/fs/file-max
临时调整(重启失效):
sudo sysctl -w fs.file-max=2097152
永久生效:
echo "fs.file-max = 2097152" | sudo tee -a /etc/sysctl.conf sudo sysctl -p
? 推荐值:一般设为 max(65535 × 预估并发进程数, 1048576),常见生产环境设 2097152(200 万)较稳妥。
补充:别漏掉 nr_open(极少需调,但超限会拦)
nr_open 是单进程理论最大 fd 数(内核编译时设定,默认约 1048576)。
若你真要设 nofile > 1048576(比如设 200 万),才需调它:
# 临时 sudo sysctl -w fs.nr_open=2097152 # 永久(加到 /etc/sysctl.conf) echo "fs.nr_open = 2097152" | sudo tee -a /etc/sysctl.conf sudo sysctl -p
正常场景无需动它 —— 65535 或 1048576 都远低于默认 nr_open。
不复杂但容易忽略











