Too many open files:文件描述符耗尽的三步排查

举报
yd_213781742 发表于 2026/11/14 16:41:09 2026/11/14
【摘要】 服务报 Too many open files 时,先按进程数 fd 找到真凶,再读 /proc/<pid>/limits 看软限制,最后确认限制由用户级、systemd 单元还是容器下发——改错层是这类问题最常见的返工点。本文给出四段可直接复制的命令。

服务突然开始报 Too many open files,重启就好,第二天又犯。多数时候不是连接泄漏,而是某个进程的 fd 上限被单个用户或单个进程的默认值卡住了。按下面三步查,比反复重启快得多。

第一步,看谁真的把 fd 用满了,而不是看系统总打开数:

# 按进程统计 fd 数量,前 10 名
for p in /proc/[0-9]*; do
  printf "%6s %s\n" "$(ls $p/fd 2>/dev/null | wc -l)" "$(cat $p/comm 2>/dev/null)"
done | sort -rn | head -10

第二步,确认这个进程的上限是多少。注意要读 /proc/<pid>/limits,ulimit -n 只对当前 shell 及其子进程有效,看不到别人的:

PID=$(pgrep -f your-service | head -1)
grep "open files" /proc/$PID/limits
# Max open files  1024  4096  files

左列是软限制,右列是硬限制。软限制才是进程实际能用的数量。

第三步,如果是 systemd 托管的服务,/etc/security/limits.conf 对它不生效——那是给 PAM 登录会话用的。正确的位置是单元文件:

systemctl edit your-service
# 写入:
# [Service]
# LimitNOFILE=65535
systemctl daemon-reload && systemctl restart your-service

验证是否真的生效,重启后再读一次 limits:

grep "open files" /proc/$(pgrep -f your-service | head -1)/limits

坑在这里:改完 limits.conf 就以为万事大吉,重启服务发现还是 1024。因为 systemd 不走 PAM,服务继承的是单元里声明的值。容器里同理,docker run --ulimit nofile=65535:65535,编排环境要写在 compose 或 pod 的 securityContext 里。

小结:fd 报错先按进程数一遍,再看该进程的软限制,最后确认限制是从哪一层下发的——用户级、单元级、容器级各管一段,别改错了地方。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。