首页/系统/信创系统运维速查/句柄耗尽(Too many open files)
常见问题65 条

句柄耗尽(Too many open files)

应用报 Too many open files:完看进程实际句柄数与各层上限,区分上调上限与处理泄漏,systemd 服务需用 drop-in 设置。

信创系统运维速查系统更新于 2026-10-13

句柄耗尽怎么处理

应用报 Too many open files 表示进程可用的文件描述符数量已达上限。要区分两种情况:一是并发量本来就大,需要合理上调上限;二是句柄持续增长不释放(常见于连接或文件未关闭),此时上调只是把问题推迟。排查要先看进程当前实际句柄数与各层限制,再按类型统计句柄构成。需要注意 systemd 托管的服务不读取 limits.conf,要用 drop-in 方式设置上限。

基本信息

进程限制cat /proc/<PID>/limits 查看实际生效上限
实际占用统计 /proc/<PID>/fd 下的句柄数量
系统级cat /proc/sys/fs/file-nr 查看已分配与上限
会话级ulimit -n 查看当前会话限制
服务级systemd 用 drop-in 设置 LimitNOFILE

典型使用场景

  • 高并发服务运行一段时间后报句柄不足,需要判断是容量还是泄漏
  • 排查连接泄漏:按句柄类型统计数量,找出异常增长的类型
  • systemd 服务上调上限后仍不生效,需要确认配置位置是否正确
  • 数据库或中间件调优时核对句柄上限是否符合官方建议
  • 故障前采集句柄增长曲线,作为容量规划依据
  • 批量巡检句柄使用情况,提前发现趋近上限的实例

判断与调整

判断与调整
cat /proc/<PID>/limits | grep -i 'open files'   # 进程实际生效的上限
ls /proc/<PID>/fd | wc -l                       # 当前实际句柄数
cat /proc/sys/fs/file-nr                        # 系统级已分配与上限
ulimit -n                                       # 当前会话上限
sudo lsof -p <PID> | awk '{print $5}' | sort | uniq -c | sort -rn | head   # 按类型统计
ulimit -n 65535                                 # 会话级示例
# systemd 服务用 drop-in(limits.conf 对服务不生效):
# systemctl edit app-web
# [Service]
# LimitNOFILE=65535
systemctl daemon-reload && systemctl restart app-web
systemctl show app-web -p LimitNOFILE           # 确认服务实际限制

各层限制与查看方式

层级查看方式注意
系统级/proc/sys/fs/file-nr决定整机可用总量
会话级ulimit -n只影响当前会话及其子进程
进程级/proc/<PID>/limits进程真实生效值,以此为准
服务级systemctl show -p LimitNOFILE服务不读 limits.conf
实际占用统计进程 fd 目录反映真实使用而非配置
上调上限只是止血:如果句柄随运行时间持续增长,说明存在连接或文件未释放的问题,要把最新上限再次吃满,必须按类型统计并定位泄漏点。
给 systemd 服务调上限要用 drop-in 或单元文件里的 LimitNOFILE,改 limits.conf 对该服务无效,这是「改完没变化」最常见的原因。

易错点

  • 只调上限不看增长曲线,泄漏型问题会把新上限再次吃满,告警周期性出现
  • 改 limits.conf 试图影响 systemd 服务,配置位置错误导致调整无效
  • 只看会话级 ulimit 就当作进程上限,忽略进程实际生效值来自服务配置
  • 句柄数接近上限但不告警,等到业务失败才发现,缺少趋势监控

数据来源与参考

  • man 2 getrlimit
  • man 5 limits.conf
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌