文件句柄耗尽排查是什么场景
服务突然报打开文件过多、无法接受新连接,通常是进程持有的文件描述符达到了上限,或者存在句柄泄漏导致数量持续上涨。排查方向分三步:量化现状(当前用了多少、上限是多少),分析句柄集中在什么类型(网络连接、普通文件、管道),观察数量是否持续增长。临时提高上限只能缓解,如果数量一路走高,真正要修的是没有被关闭的连接或文件。
基本信息
| 适用平台 | GNU/Linux(/proc 文件系统与 lsof) |
|---|---|
| 典型症状 | 报打开文件过多、无法接受新连接 |
| 三步排查 | 量化现状、分布分析、观察增长 |
| 关键路径 | /proc/进程号/fd 与 /proc/进程号/limits |
| 辅助工具 | lsof 按进程统计句柄类型分布 |
| 上限调整 | 运行期可在线调整,持久化要改服务单元或系统限制 |
典型使用场景
- 服务报无法接受新连接或打开文件失败。
- 排查句柄泄漏:确认数量是否随时间持续上涨。
- 评估是否需要提高服务的句柄上限。
- 定位句柄集中在网络连接还是普通文件。
- 变更上限后验证服务是否恢复正常。
排查流程
排查流程
pid=$(pgrep -f 'app-server' | head -1) # 定位进程号
ls /proc/$pid/fd | wc -l # 当前句柄数量
cat /proc/$pid/limits | grep -i files # 该进程的上限
lsof -p $pid | awk '{print $5}' | sort | uniq -c | sort -rn | head # 类型分布
lsof -p $pid | grep -c TCP # 连接数是否异常
watch -n 5 "ls /proc/$pid/fd | wc -l" # 观察是否持续上涨
prlimit --nofile=65535:65535 --pid $pid # 在线提高上限(治标)项目与判断读法
| 项目或命令 | 含义 | 使用要点 |
|---|---|---|
| 句柄数量 | 当前打开的数量 | 与上限对比才能判断是否触顶 |
| 上限 | 进程级限制 | 由系统限制与服务单元共同决定 |
| 类型分布 | 文件、连接、管道 | 集中在哪一类就能定位泄漏源 |
| 增长趋势 | 是否持续上涨 | 持续上涨即可判定为泄漏 |
| 在线提限 | 立即生效 | 治标手段,重启后可能失效 |
| 持久化设置 | 改服务单元或系统配置 | 必须重启服务才生效 |
句柄数持续增长就是泄漏,提高上限只是把问题往后拖;必须找到没有关闭的连接或文件,从代码或配置层面修复。
长连接服务天然持有大量句柄:判断依据是增长趋势与上限余量,而不是绝对数量,否则会把正常水位误判为泄漏。
运行期调整上限只影响当前进程实例,重启后会回到配置文件中的值;要持久生效必须修改服务单元或系统级限制配置。