做后端稳定性治理的同学,大概率都遇到过 too many open files 故障。以往碰到文件句柄飙升,第一反应都是查代码:文件流、网络连接、临时文件有没有正常关闭。
但这次线上案例彻底刷新认知:业务代码全部规范释放 IO 资源,句柄依旧稳步爬坡逼近阈值,深挖后才发现,坑藏在我们常用的性能监控工具里。
线上文件句柄大盘出现异常,集群多个节点曲线同步稳步上涨,长期卡在 1000 警戒线之上,峰值突破 1200。

一旦句柄数量触达系统 ulimit -n 上限,服务会无法创建文件、新建网络连接,直接引发接口报错、服务瘫痪,属于高危稳定性隐患。
起初下意识排查业务导出、文件读写模块,逐行核对代码,全部使用 try-with-resources 自动关闭流,不存在编码层面的句柄泄漏,问题瞬间陷入僵局。
拿到故障 Java 进程 PID,执行命令导出所有打开的文件描述符:
lsof -p ${进程PID}对 lsof 输出做分类统计,一眼发现异常:系统中存在608 个 [perf-event] 类型句柄,普通文件、TCP 连接数量长期稳定,完全没有增长迹象。
很多开发对这个类型很陌生,简单拆解: perf-event 是 Linux 内核提供的抽象文件(lsof 中标记为 a_inode),不对应磁盘实体文件,专门用于内核采集性能指标:CPU 周期、缓存缺失、线程栈采样等。
在 Java 服务中,只会由性能剖析工具创建:
工具原理:会为每个线程单独创建 perf-event 句柄,依托内核完成栈采样,以此生成 CPU 火焰图、定位耗时代码。
梳理近期线上变更,几天前刚批量开启阿里云 APM 自带的持续性能分析功能,底层基于 Arthas 集成 async-profiler,实现 7×24 小时不间断 CPU 采样。
stop能主动释放资源,平台后台常驻采样无法自动回收 fd。在阿里云后台关闭全量实例的持续性能分析功能,滚动重启 Pod 后,600 + 个 perf-event 句柄全部释放,句柄曲线立刻平稳,不再持续上涨。
stop释放资源,不要直接挂起会话;在 Pod 配置中提升进程最大文件句柄,预留缓冲空间,防止突发泄漏直接击穿阈值:
securityContext:
limits:
nofile: 65535perf-event句柄,极易被忽略;lsof分类统计句柄类型,a_inode/perf-event是性能工具专属标识;后续我会整理一套文件句柄泄漏一键排查脚本,线上碰到同类问题可以快速定位根因,关注专栏不错过干货。
你们线上有没有踩过监控工具带来的资源泄漏坑?评论区一起交流避坑经验。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。