Too many open files:文件描述符耗尽的三步排查
【摘要】 服务报 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)