linux限制最大打开文件数需分进程级和系统级两层设防,仅调一边会导致“too many open files”错误;须用ulimit -n、ls /proc/pid/fd、cat /proc/sys/fs/file-max定位瓶颈,再分别配置limits.conf、sysctl.conf及systemd service文件。

Linux 系统中限制最大打开文件数,本质是分层设防:既要管住单个进程能用多少句柄(进程级),也要控制整个系统最多能分配多少句柄(系统级)。只调一边,高并发时仍会报 “Too many open files”,而且排查困难。
查清当前瓶颈再动手
先运行三条命令,快速定位是否已临界:
-
ulimit -n→ 看当前会话软限制(常见默认 1024,明显偏低) -
ls /proc/$(pgrep -f "your-service")/fd | wc -l→ 查目标服务实际用了多少句柄,超软限制 80% 就该调了 -
cat /proc/sys/fs/file-max→ 看系统总上限,建议 ≥ 预估最大并发连接数 × 1.2(比如 10 万连接,设到 12 万起)
永久设置每个用户的进程级限制
编辑 /etc/security/limits.conf,追加四行(* 表示所有普通用户):
* soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc 65535
确保 /etc/pam.d/common-session(Debian/Ubuntu)或 /etc/pam.d/login(RHEL/CentOS)里有这一行:session required pam_limits.so
改完需重新登录或重启服务进程,仅改文件不重启无效。
同步提升系统级总句柄池
临时验证用:sudo sysctl -w fs.file-max=1048576
永久生效:往 /etc/sysctl.conf 末尾加一行fs.file-max = 1048576
然后执行 sudo sysctl -p 加载。注意别盲目拉太高——每千个句柄约占 1KB 内核内存,1GB 内存服务器设到 100 万较稳妥。
systemd 服务必须单独声明限制/etc/security/limits.conf 对 systemd 托管的服务基本无效。必须在 service 文件里显式写:
[Service] LimitNOFILE=65535 LimitNPROC=65535
改完运行 sudo systemctl daemon-reload && sudo systemctl restart your-service,再用 cat /proc/PID/limits | grep "Max open files" 确认值已生效。
不复杂但容易忽略











