必须同步调五层:soft/hard nofile、limits.conf、systemd limitnofile、内核fs.file-max、应用层连接池与worker配置,缺一不可;先用ulimit -sn/-hn、su切换用户、cat /proc/sys/fs/file-max、ls /proc/pid/fd等命令精准定位瓶颈层。

单靠 ulimit -n 65535 根本撑不住百万并发,必须同步调五层:soft/hard nofile、limits.conf、systemd LimitNOFILE、内核 fs.file-max、应用层连接池与 worker 配置。
查清当前哪一层卡住了 fd
别一上来就改配置,先定位瓶颈点:
-
ulimit -Sn和ulimit -Hn查当前 shell 的软硬限制;若软限远低于硬限,说明软限被主动压低 -
su - www-data -c 'ulimit -n'切到服务用户验证——很多服务报错但 root 下ulimit -n显示正常,就是没继承到用户级限制 -
cat /proc/sys/fs/file-max看系统总池子,百万连接至少要设到2097152(2048k),否则所有进程加起来就爆了 -
ls /proc/$(pidof nginx)/fd | wc -l查真实已用 fd 数,比日志里 “Too many open files” 更准
临时调高只对当前 shell 有效,且不能超硬限
调试时快速验证是否是 fd 不足导致的问题:
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
- 执行
ulimit -Sn 65535提升软限制(前提是硬限 ≥ 65535) - 若报
Operation not permitted,需先提硬限:sudo ulimit -Hn 65535,再提软限 - 该操作只影响当前终端及其子进程,已运行的 nginx/java 进程完全不受影响
- 别用
ulimit -n 65535简写——它默认只改软限,但不显式声明易被误读
永久生效必须过 PAM + limits.conf + systemd 三关
生产环境改完不生效?八成栽在这三处没配全:
- 在
/etc/security/limits.conf末尾加两行:* soft nofile 65535和* hard nofile 65535(或指定用户如www-data) - 确认
/etc/pam.d/common-session含session required pam_limits.so,缺则手动加 - 对 systemd 托管的服务(nginx/redis/java),
limits.conf完全无效,必须执行:sudo systemctl edit nginx.service,填入:[Service]<br>LimitNOFILE=65535
,再sudo systemctl daemon-reload && sudo systemctl restart nginx - 验证是否真生效:
systemctl show nginx --property LimitNOFILE或cat /proc/$(pidof nginx)/limits | grep "Max open files"
内核级 fs.file-max 是兜底红线,百万并发必须调
哪怕每个进程都设了 65535,若 fs.file-max 只有 10 万,全局 fd 池一满,新连接连 accept 都失败:
- 临时调高:
sudo sysctl -w fs.file-max=2097152 - 永久写入:
echo "fs.file-max = 2097152" | sudo tee -a /etc/sysctl.conf && sudo sysctl -p - 注意:这个值不是越大越好,它会占用内核内存(约每 fd 1KB),2048k ≈ 2GB 内核内存预留
- 顺手检查
net.nf_conntrack_max,它也要 ≥fs.file-max,否则连接跟踪表先满
真正卡住百万并发的,往往不是某一层没调,而是某一层调了但其他层仍卡在默认值——比如 systemd 服务没配 LimitNOFILE,它就永远按 1024 起步;又比如 fs.file-max 没动,所有进程加起来撑不过 6 万连接。每一层都要单独验证,不能只信 ulimit -n 的输出。










