最稳妥的永久方案是修改/etc/security/limits.conf,但需用户重新登录或服务重启才生效;临时用ulimit -n仅影响当前shell。软限制决定实际打开文件数,硬限制为其上限;ulimit -n查软限,ulimit -Hn查硬限。常见错误是服务日志报“Too many open files”但ulimit -n显示已调高,根源在于服务未继承新限制——如sudo -u user cmd不触发PAM、systemd服务默认不读limits.conf,必须在unit文件中显式配置LimitNOFILE并重载重启。

直接改 /etc/security/limits.conf 是最稳妥的永久方案,但必须配合用户重新登录或服务重启才生效;临时用 ulimit -n 只影响当前 shell,对已启动的服务无效。
怎么看当前限制值?
软限制决定进程实际能打开多少文件,硬限制是软限制的上限。不加参数的 ulimit -n 显示软限制,ulimit -Hn 看硬限制,ulimit -Sn 看软限制。
常见错误现象:服务日志里出现 Too many open files,但 ulimit -n 显示 65535 —— 这说明限制已调高,但服务不是以该用户身份、在该 shell 环境下启动的,没继承到新限制。
- 查系统级总限制(所有进程共用):
cat /proc/sys/fs/file-max - 查某用户限制:先
su - username,再执行ulimit -n - 查某个运行中进程实际使用的 fd 数:
ls /proc/<pid>/fd | wc -l</pid>
为什么改了 limits.conf 还不生效?
因为 /etc/security/limits.conf 的规则只在用户登录时由 PAM 模块加载一次,不是实时生效的配置文件。
典型踩坑场景:
- 用
sudo -u user command启动服务 → 不触发 PAM 登录流程 → 限制不变 - systemd 服务默认不读取 limits.conf → 必须在 service 文件里显式设置
LimitNOFILE=65535 - 容器内进程受宿主机和容器 runtime 双重限制 → 即使宿主机改了,也要在
docker run时加--ulimit nofile=65535:65535
验证是否生效:切到目标用户后执行 ulimit -n,再启动服务,而不是只看 root 下的输出。
systemd 服务怎么设文件数限制?
systemd 忽略 limits.conf,必须在 unit 文件里声明。否则即使用户登录时限制正确,服务仍按 systemd 默认的 1024 起步。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
操作步骤:
- 编辑服务文件:
sudo systemctl edit servicename.service - 写入:
[Service] LimitNOFILE=65535
- 重载并重启:
sudo systemctl daemon-reload && sudo systemctl restart servicename - 确认生效:
systemctl show servicename --property LimitNOFILE
注意:如果服务由 root 启动但切换到普通用户运行(如 nginx 的 user www-data),则 LimitNOFILE 必须设在 service 定义里,不能依赖该用户的 limits.conf。
要不要动 fs.file-max?
一般不用动。这个值是整个系统能分配的文件描述符总数,现代服务器默认都在几十万级别(如 cat /proc/sys/fs/file-max 输出 483438),远高于单个服务需求。
只有当你遇到以下情况才需要调大:
- 单机跑上百个高并发服务,且每个都设了 65535 以上
- 监控发现
cat /proc/sys/fs/file-nr第二个数字长期接近file-max
临时改:sudo sysctl -w fs.file-max=500000;永久改:往 /etc/sysctl.conf 加 fs.file-max = 500000,再 sudo sysctl -p。
真正容易被忽略的是:改完 limits.conf 后忘记让服务进程重新加载环境,或者误以为 ulimit -n 在 root 下生效就等于所有进程都生效了。

















