Too many open files:句柄上限的三层配置与真实案例

Linux · 3 分钟阅读· 321 次阅读

高并发服务跑一段时间后报 Too many open files,重启就好,过几天又出现。这通常不是限制太小,而是句柄在泄漏。

但先要把三层限制配对:内核 fs.file-max、用户 limits.conf、进程自身(systemd 的 LimitNOFILE 会覆盖前两者)。

先说结论

先确认限制值,再查是否泄漏,最后才考虑调大。 只调大不查泄漏,等于把问题推迟几天。

  • ulimit -n 与 cat /proc//limits 对比
  • systemd 服务加 LimitNOFILE=65535
  • lsof -p | wc -l 看句柄数与类型
  • 找出增长最快的类型(socket/文件/管道)
  • 应用层修连接泄漏

先把问题说清楚

systemd 启动的服务不读 limits.conf,必须用 LimitNOFILE 显式设置——这是最常见的坑。

句柄泄漏的典型形态:连接用完没 close、异常分支漏了 finally、事件监听器只加不减。

具体怎么做

按顺序执行,每步都验证完再进下一步:

  • ulimit -n 看当前 shell 限制,cat /proc//limits 看进程真实限制
  • 按句柄类型统计:lsof -p | awk '{print $5}' | sort | uniq -c | sort -rn
  • 观察增长曲线:每分钟统计一次,线性增长基本就是泄漏
  • 系统层调 fs.file-max,用户层调 limits.conf,服务层加 LimitNOFILE
  • 应用层修复泄漏点,并加句柄数监控

参数与成本对照

把关键数值摊开,方便判断该选哪条路:

层级 配置位置 说明
内核 /etc/sysctl.conf fs.file-max 全系统上限
用户 /etc/security/limits.conf 登录会话生效
服务 systemd unit LimitNOFILE 覆盖前两者
进程 ulimit -n(继承) 取决于启动方式

Too many open files

几个容易踩的坑

下面这些是最常见的错误做法:

  • 只改 limits.conf 不重启会话:不生效
  • 用 systemd 起服务却只改 limits.conf:同样不生效
  • 把上限调到 100 万却不看内存:句柄也占内存
  • 忽略容器内的 nofile 限制与宿主不同

最后补两句

句柄问题的正确顺序是:看限制 → 看类型 → 看增长 → 修泄漏 → 再调上限。

工具是手段,理解机制才是能力。命令记不住没关系,知道「该看什么」就够了。

评论 (3)

阿
阿哲

照着做了一遍,确实少走弯路。第二步最容易漏,建议顺手加个检查清单。

南
南风

比「一键脚本」有用多了,知道为什么比知道怎么做重要。

K
Kevin

补充一句:不同版本行为会变,动手前先确认自己的版本号。

发表评论

验证码

提交后需站长审核,通过后才会显示。