ulimit -n 65536重启后失效是因为该命令仅作用于当前shell会话,不持久化;真正生效需同步配置/etc/security/limits.conf(并确保pam加载pam_limits.so)、systemd服务的limitnofile参数及内核fs.file-max。

为什么 ulimit -n 65536 重启后就失效
因为 ulimit 命令只影响当前 shell 及其子进程,属于运行时设置,不写入任何持久化配置。哪怕你用 root 执行了 ulimit -Hn 65536,只要新登录、su 切换用户、或 SSH 重连,限制就回落到 /etc/security/limits.conf 定义的值(或默认值 1024)。系统根本不会记住你上一次手动敲过的命令。
/etc/security/limits.conf 的写法陷阱
这个文件是 PAM 模块读取的,但生效有严格前提:必须确保对应服务(如 sshd、login)启用了 pam_limits.so。很多最小化安装的系统(比如某些 Alpine 或精简版 CentOS)默认没启用,导致你改了 limits.conf 也完全不生效。
-
www soft nofile 65536和www hard nofile 65536是正确写法;错写成www nofile 65536(缺 soft/hard)会被忽略 - 用
*表示所有用户时,root默认不受影响(部分发行版对 root 有特殊策略),需单独加root行 - 数值不能带单位(如
65536k)、不能有空格(如nofile 65536中间多空格会解析失败) - 修改后必须新开一个登录会话(不是
source或重新加载 shell)才能验证
systemd 服务绕过 limits.conf 的常见原因
如果你的服务是通过 systemd 启动(比如 mysql.service、nginx.service),它默认不读 /etc/security/limits.conf —— 这是最容易被忽略的一点。即使用户登录时 ulimit -n 显示 65536,该服务进程的 LimitNOFILE 仍可能是 1024。
- 检查方法:
cat /proc/$(pidof mysqld)/limits | grep "Max open files" - 修复方式:在 service 文件中显式设置,例如在
[Service]段加LimitNOFILE=65536,然后systemctl daemon-reload && systemctl restart mysql - 全局 fallback:可改
/etc/systemd/system.conf中的DefaultLimitNOFILE=65536,但会影响所有 systemd 服务
别漏掉内核级总上限 fs.file-max
/etc/security/limits.conf 控制的是**单个用户/进程**的文件句柄数,而整个系统能分配的句柄总数由内核参数 fs.file-max 决定。如果这个值太小(比如默认的 80000),即使你把每个进程设到 65536,多个进程一跑满,照样报 Too many open files。
- 临时调大:
sysctl -w fs.file-max=2097152 - 永久生效:往
/etc/sysctl.conf加一行fs.file-max = 2097152,再执行sysctl -p - 验证:
cat /proc/sys/fs/file-max











