请求排查Tomcat因Too many open files导致API故障的根因及方案
问题分析与解决方案
根本原因定位
- 文件句柄耗尽:核心触发点是系统或Tomcat进程的最大打开文件数限制被打满,引发连锁故障:
- Tomcat无法创建新Socket,直接导致客户端请求接收失败,抛出
java.io.IOException: Too many open files - 与Riak集群的连接尝试因句柄不足持续失败,循环重试进一步加剧资源消耗,最终导致所有Riak节点不可达,出现
Unable to connect successfully to {{Server}}. Trying another node...Too many open files报错
- Tomcat无法创建新Socket,直接导致客户端请求接收失败,抛出
- 常见诱因:
- Tomcat运行用户的文件句柄限制过低,未匹配业务负载需求
- 应用存在Socket连接泄漏:比如与Riak的连接未正确关闭、长连接未设置超时回收,导致句柄长期占用
- 短时间内突发高并发请求,超出当前句柄限制的承载能力
临时修复(已完成)
- 重启Tomcat进程:强制释放所有占用的文件句柄,快速恢复服务
长期修复与优化方案
1. 调整文件句柄限制
- 系统级配置:修改
/etc/security/limits.conf,添加或更新:
(tomcat soft nofile 65535 tomcat hard nofile 65535tomcat为运行Tomcat的用户,数值可根据业务负载调整,建议至少设置为65535) - 进程级配置:在Tomcat启动脚本
catalina.sh中添加:
确保进程启动时加载新的句柄限制ulimit -n 65535 - 验证生效:执行
ulimit -n(切换至Tomcat用户)或lsof -p <Tomcat_PID> | wc -l查看当前句柄使用情况
2. 排查并修复连接泄漏
- 检查Riak客户端代码:确保所有连接对象使用后通过
close()方法释放,或采用try-with-resources语法自动管理资源 - 配置Riak连接池:设置合理的最大连接数、连接超时、空闲连接回收时间,避免连接长期闲置占用句柄
- 排查异常连接:使用
netstat -anp | grep <Tomcat_PID>或ss -anp | grep <Tomcat_PID>查看连接状态,重点关注TIME_WAIT/CLOSE_WAIT状态的连接是否过多
3. 监控与预警
- 配置句柄使用率告警:将阈值设为70%,实时监控Tomcat进程及系统级的文件句柄剩余量
- 定期分析日志:跟踪
Too many open files报错的出现频率,提前发现负载异常或句柄泄漏迹象
内容的提问来源于stack exchange,提问作者Ramakanth Ram
相关产品推荐
相关产品推荐

