ulimit -n 设置不生效是因为它仅影响当前shell及其直接子进程,且不能突破硬限制;需先查ulimit -Hn,再通过/etc/security/limits.conf(PAM会话)或systemd的LimitNOFILE(服务)分别配置,并验证/proc/PID/limits。

为什么 ulimit -n 设置后不生效?
直接在终端执行 ulimit -n 65536 看似成功,但新启动的子进程(比如 nginx、redis-server)仍卡在默认的 1024,这是因为 ulimit 只影响当前 shell 及其**直接派生**的进程,且无法突破系统级硬限制(hard limit)。你得先确认当前硬限制:运行 ulimit -Hn,如果输出是 4096,那 -n 65536 就会静默失败。
实操建议:
- 先用
ulimit -Hn查硬限制,若低于目标值,必须改系统配置,不能只靠命令行 - 临时提硬限需 root 权限:
sudo ulimit -Hn 65536(仅当前 root shell 有效) - 普通用户无法提升自己的硬限制,这是内核强制的安全边界
如何永久修改所有用户的默认 soft/hard 限制?
修改 /etc/security/limits.conf 是通用方案,但它只对通过 PAM 登录的会话生效(比如 ssh、console),对 systemd 服务、nohup 或 cron 启动的进程无效。
实操建议:
- 在
/etc/security/limits.conf底部追加两行:* soft nofile 65536<br>* hard nofile 65536
(*表示所有用户;若只配某用户,把*换成用户名) - 确保
pam_limits.so已启用:检查/etc/pam.d/common-session是否含session required pam_limits.so - 改完需重新登录(不是
source或重启 terminal),否则 shell 不重载 limits
systemd 服务怎么绕过 limits.conf?
现代 Linux 发行版中,systemd 完全忽略 limits.conf,它用自己的机制管理资源限制。如果你用 systemctl start nginx,ulimit 配置再全也没用。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
实操建议:
- 编辑服务单元文件:
sudo systemctl edit nginx(推荐,避免改原始文件) - 写入:
[Service]<br>LimitNOFILE=65536
(这等价于ulimit -n 65536,同时设 soft/hard) - 若需区分 soft/hard,用
LimitNOFILESoft=和LimitNOFILEHard=(仅较新 systemd 支持) - 重载并重启:
sudo systemctl daemon-reload && sudo systemctl restart nginx
验证进程实际拿到的 fd 限制是否生效?
别信 ulimit -n 的输出——那是当前 shell 的值。要查目标进程的真实限制,得看它的 /proc/。
实操建议:
- 先找进程 PID:
pgrep nginx或ps aux | grep redis - 查 fd 限制:
cat /proc/,输出类似:/limits | grep "Max open files" Max open files 65536 65536 files
(两列数字分别代表 soft/hard) - 如果看到
1024或4096,说明配置没打到该进程,回头检查是 PAM 还是 systemd 路径没走对 - 注意:容器内进程受宿主机 + 容器 runtime 双重限制,
docker run --ulimit nofile=65536:65536必须显式传参
改 ulimit 最容易被忽略的是“生效路径”——同一台机器上,ssh 登录的用户、systemd 服务、docker 容器、crond 任务,各自走完全不同的限制加载链,混用配置会导致一半生效一半失效。










