文件句柄数超限
2026/7/10 7:02:58 网站建设 项目流程

目录标题

    • @[TOC](目录标题)
    • 一、先理解告警在说什么(避免误判)
      • 1️⃣ node_exporter 监控的是什么
      • 2️⃣ 为什么危险
    • 二、第一步:立刻判断「是真快爆了,还是阈值太低」
      • 1️⃣ 看系统总 FD 上限
      • 2️⃣ 当前已用 FD 数
      • 3️⃣ 计算使用率
        • 判断标准(经验值)
    • 三、第二步:快速定位——是谁在吃 FD(最关键)
      • 1️⃣ 找 FD 使用最多的进程(Top 排行)
      • 2️⃣ 把 PID 翻译成进程名
    • 四、第三步:判断是「正常高并发」还是「FD 泄露」
      • 1️⃣ 看 FD 类型分布(非常重要)
      • 2️⃣ socket 多 → 看网络连接
      • 3️⃣ 文件多 → 看谁没 close
    • 五、第四步:常见“真凶”模式(结合你的环境)
      • 🚩 模式 1:数据库连接池失控
      • 🚩 模式 2:日志 / 文件句柄泄露
      • 🚩 模式 3:K8s 组件泄露(较常见)
    • 六、第五步:临时止血 vs 根因治理
      • 🔧 临时止血(不要当最终方案)
        • 1️⃣ 提高系统级上限
        • 2️⃣ 提高进程级限制
      • 🧠 根因治理(真正该做的)
    • 七、你可以直接照这个“最短排查路径”跑

一、先理解告警在说什么(避免误判)

1️⃣ node_exporter 监控的是什么

通常告警来自:

node_filefd_allocated node_filefd_maximum

node_filefd_allocated / node_filefd_maximum

1657,320表示的是:
👉当前内核已分配的 file descriptor 总数

不是单进程,而是整台主机


2️⃣ 为什么危险

当 FD 接近上限时,会出现:

  • accept()失败

  • open()返回EMFILE / ENFILE

  • 新 TCP 连接失败

  • kubelet / containerd / DB 进程异常

  • 表象可能是:

    • 服务超时
    • 连接数异常
    • “偶发性”不可恢复故障

👉这是系统级“硬资源耗尽”,比 CPU 高更危险


二、第一步:立刻判断「是真快爆了,还是阈值太低」

1️⃣ 看系统总 FD 上限

cat/proc/sys/fs/file-max

例如:

1048576

2️⃣ 当前已用 FD 数

cat/proc/sys/fs/file-nr

输出示例:

667520 0 1048576

解释:

已分配FD 未使用(废弃) 最大值

👉核心看第一个数字

3️⃣ 计算使用率

awk'{printf "%.2f%%\n",$1/$3*100}'/proc/sys/fs/file-nr
判断标准(经验值)
使用率结论
<50%安全
50–70%关注
70–85%高风险
>85%随时炸

三、第二步:快速定位——是谁在吃 FD(最关键)

1️⃣ 找 FD 使用最多的进程(Top 排行)

forpidin/proc/[0-9]*;doecho"$(ls-1 $pid/fd2>/dev/null|wc-l)$(basename$pid)"done|sort-nr|head-20

输出示例:

124532 32456 98321 1789 ...

2️⃣ 把 PID 翻译成进程名

ps-fp32456

或:

cat/proc/32456/comm

🚨如果前 1–2 个进程占了 70%+ FD,99% 是泄露或配置不合理


四、第三步:判断是「正常高并发」还是「FD 泄露」

1️⃣ 看 FD 类型分布(非常重要)

ls-l /proc/<PID>/fd|awk'{print$NF}'|sed's/.*://'|sort|uniq-c

重点关注:

类型含义
socket网络连接
anon_inodeeventfd / epoll
普通文件文件未关闭
pipe管道泄露

2️⃣ socket 多 → 看网络连接

ss -anp|grep<PID>|wc-l

进一步:

ss -s

关注:

  • ESTAB 数量
  • TIME_WAIT 是否异常
  • CLOSE_WAIT(最危险,典型 FD 泄露

3️⃣ 文件多 → 看谁没 close

lsof-p<PID>|head

是否看到:

  • 相同路径被打开成千上万次
  • 已删除文件(deleted)仍被占用

五、第四步:常见“真凶”模式(结合你的环境)

结合你之前的背景(K8s / DB / 存储)👇

🚩 模式 1:数据库连接池失控

特征:

  • socket FD 爆炸
  • CLOSE_WAIT 多
  • 进程:postgres / oracle / oceanbase / app

原因:

  • 应用未关闭连接
  • 连接池 max 不设
  • 异常路径没 close

🚩 模式 2:日志 / 文件句柄泄露

特征:

  • 普通文件 FD 激增
  • 大量(deleted)文件

原因:

  • 日志轮转不 reload
  • 应用反复 open 不 close

🚩 模式 3:K8s 组件泄露(较常见)

进程:

  • kubelet
  • containerd
  • dockerd(老集群)

特征:

  • anon_inode / epoll 多
  • socket 多
  • 节点越跑越高,重启即恢复

六、第五步:临时止血 vs 根因治理

🔧 临时止血(不要当最终方案)

1️⃣ 提高系统级上限
sysctl -w fs.file-max=2097152

持久化:

echo"fs.file-max=2097152">>/etc/sysctl.conf sysctl -p
2️⃣ 提高进程级限制
ulimit-n

systemd 服务:

[Service] LimitNOFILE=1048576

🧠 根因治理(真正该做的)

  • 找到FD Top 进程

  • 明确是:

    • 连接池参数问题
    • 异常路径未 close
    • 内核 / runtime bug
  • 用:

    • strace -p <pid> -e trace=open,close
    • 或应用级 metrics

七、你可以直接照这个“最短排查路径”跑

cat/proc/sys/fs/file-maxcat/proc/sys/fs/file-nrforpidin/proc/[0-9]*;doecho"$(ls-1 $pid/fd2>/dev/null|wc-l)$(basename$pid)"done|sort-nr|headps-fp<TOP_PID>ls-l /proc/<TOP_PID>/fd|headss -anp|grep<TOP_PID>|wc-l

如果你愿意,下一步我可以直接帮你做

  • 结合 node_exporter 指标,设计一套 FD 泄露预警模型
  • 把这次排查整理成一份《文件句柄耗尽故障排查 SOP》
  • 你把 Top 进程 + FD 类型贴出来,我直接帮你判断是不是泄露

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询