系统级句柄上限由fs.file-max控制,单个进程上限受limits.conf(仅登录用户)、systemd defaultlimitnofile(服务进程)及内核nr_open三者共同约束,四层需全部配置才能支撑高并发。

系统级句柄总数:改 fs.file-max 才管用
单个进程开再多句柄,加起来超过系统总上限照样报 too many open files。这个总上限由内核参数 fs.file-max 控制,不是用户配置文件能改的。
-
cat /proc/sys/fs/file-max查当前值; - 临时调高:直接写入
echo 6553560 > /proc/sys/fs/file-max; - 永久生效:往
/etc/sysctl.conf追加fs.file-max = 6553560,再执行sysctl -p; - 注意:该值不能超过内核编译时的硬上限(通常够用),但必须大于你所有服务的句柄需求之和。
单个进程最大句柄数:/etc/security/limits.conf 只对登录用户有效
这个文件只影响通过 shell 登录的用户启动的进程(比如你 ssh 进去后手动起的服务),对 systemd 管理的 service 完全无效。
- 加两行:
* soft nofile 1024000和* hard nofile 1024000; - 改完必须重新登录(不是
source或systemctl daemon-reload); - 验证:登录后运行
ulimit -n,或查/proc/self/limits中Max open files行; - 坑点:如果设的
hard nofile超过内核/proc/sys/fs/nr_open,对应用户可能直接无法登录(root 尤其危险)。
systemd 服务的句柄限制:必须改 system.conf
几乎所有生产服务(nginx、redis、java 应用等)都是 systemd service,它们完全无视 limits.conf。不改这里,调了也没用。
- 编辑
/etc/systemd/system.conf,取消注释或添加:DefaultLimitNOFILE=1024000; - 改完必须重启 systemd:先
systemctl daemon-reload,再reboot(仅 reload 不生效); - 验证某服务:查
cat /proc/$(pidof your_service)/limits | grep "Max open files"; - 更细粒度控制可单独改 service 文件,加
LimitNOFILE=1024000在[Service]段下。
别漏掉内核上限 nr_open
hard nofile 和 DefaultLimitNOFILE 都不能突破内核定义的单进程硬顶——/proc/sys/fs/nr_open。CentOS 7 默认是 1048576,但如果你设成 200 万就卡住。
- 查当前值:
cat /proc/sys/fs/nr_open; - 临时改:
echo 2097152 > /proc/sys/fs/nr_open; - 永久改:在
/etc/sysctl.conf加fs.nr_open = 2097152,再sysctl -p; - 关键点:这个值必须在改
limits.conf或system.conf之前确认,否则 root 用户可能因超限而失联。
改完这四层,才能真正撑住高并发连接。最容易被跳过的其实是 nr_open 和 systemd 的 DefaultLimitNOFILE,一漏就白调。











