解决: java.io.IOException: 打开的文件过多 的问题
问题
前一阵子公司项目做了一次压力测试, 中间出现了一个问题: 在50多个并发的时候会出现 java.io.IOException: 打开的文件过多 这个异常. 但是在没有并发的时候是不会出现这个问题的. 这个问题的出现使得项目压力测试没有办法进行下去, 所以必须要尽快解决掉.
尝试查找原因1
首先我们这次的压力测试只是测试项目的首页, 这个页面仅仅是一个商品的列表. 没有在代码中写任何读取文件的操作, 商品的数量也不是很多, 只有10多款商品. 在自己开发用的电脑上也没有出现过这种问题. 所以比较头疼. 上网查了一下, 大部分说的也都是有什么文件打开之后没有关闭, 或者有什么连接池打开之后没有关闭. 针对我们的项目没有什么参考价值. 之后又看到可能是操作系统的中打开文件的最大句柄数受限所导致的, 于是就修改了服务器的最大文件句柄数量. 但是依然没有什么用. 只不过之前是 50 并发就会出问题, 现在变成了70, 80 才会出问题. 根本原因还是没有解决.
尝试查找原因2
无脑上网搜索并尝试了之后, 没有解决问题. 于是试着自己分析一下. 因为这个异常是提示 打开的文件过多 那么一定是有一个文件打开的后并别没有关闭导致的, 那么我能不能知道服务器上所有被打开的文件, 然后查看是哪个文件打开了那么多次呢? 于是上网搜了一下, 果然是有方法的. 可以使用 lsof 命令.
lsof命令用于查看你进程开打的文件
-a:列出打开文件存在的进程;
-c<进程名>:列出指定进程所打开的文件;
-g:列出GID号进程详情;
-d<文件号>:列出占用该文件号的进程;
+d<目录>:列出目录下被打开的文件;
+D<目录>:递归列出目录下被打开的文件;
-n<目录>:列出使用NFS的文件;
-i<条件>:列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件;
-u:列出UID号进程详情;
-h:显示帮助信息;
-v:显示版本信息。
于是我在服务器上找了一下我们项目的进程号
ps -ef | grep `项目路径`
找到进程号: 22041
查看这个进程所打开的文件
lsof -p 22041
结果:

这里发现有两个xml文件被打开了非常多次, 所以有理由怀疑是因为这两个文件在打开后没有关闭造成了java.io.IOException: 打开的文件过多 这个异常.
开始解决问题
知道了问题所在, 解决起来就有思路. 首先这两个文件是 tiles 框架的配置文件, Tiles 是一种JSP布局框架. 大家可以自行百度. 这里我们用了spring 集成 tiles 中的配置. 配置项是这样的 ( 啊~ 这个配置项被层层包装在公司的框架jar包中, 一个包一个包的找, 找了半天. 愁死我了~ )
<!-- 定义Tiles模板 -->
<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="checkRefresh" value="true" />
<property name="definitions">
<list>
<value>/WEB-INF/layouts/**/tiles-*.xml</value>
</list>
</property>
</bean>
在这里 发现 这个配置的 checkRefresh 属性比较可疑, 我怀疑是不是在每次请求都会读取文件并且没有关闭这个文件. 但是在代码中我没有找到相应打开并读取文件的地方, 于是尝试把这个属性去掉. 并且再次发版并测试. 问题已经被解决, 再次使用 lsof 命令后没有再出图中的文件被大量打开的问题.
另外
因为 lsof 命令是linux 系统中独有的, win系统下怎么排查问题呢?
win 系统下也有一个类似 lsof 的软件 叫做 procexp. 这个软件也可以检索当前系统中打开了那些文件, 还是挺好用的.
总结一下
出现这个问题的时候因为是第一次遇到, 直接上网搜索出来的内容大部分都是要改操作系统文件句柄数量的, 并没有从根本上解决这个问题, 所以还是要具体分析问题的根本原因. 另外要多学习 linux 的命令, 真的是好用.
解决: java.io.IOException: 打开的文件过多 的问题的更多相关文章
- Tomcat9.0.13 Bug引发的java.io.IOException:(打开的文件过多 Too many open files)导致服务假死
问题背景: 笔者所在的项目组最近把生产环境Tomcat迁移到Linux,算是顺利运行了一段时间,最近一个低概率密度的(too many open files)问题导致服务假死并停止响应客户端客户端请求 ...
- 解决java.io.IOException: Cannot run program "cygpath": CreateProcess error=2, 系统找不到指定的文件 的错误
一.外部环境: 系统环境:Windows 8 磁盘分区:只有C盘 开发环境:IntelliJ IDEA Community Edition 2016.1.3(64) 执行代码:rdd.saveAsTe ...
- android环境下解决java.io.IOException: Malformed ipv6异常的方法
今天做客户端想服务端提交信息的时候,报出了如标题所显示的方法 方法以及参数如下: 输入的参数为:http://192.168.1.173:8080/Api/petinfo/petinfo?flag=a ...
- 记录解决java.io.IOException: Server returned HTTP response code: 500 for URL:xxxxxxxx
踩坑经历 因为项目需要去对接别的接口,使用URLConnection POST请求https接口,发送json数组时遇到java.io.IOException: Server returned HTT ...
- 解决java.io.IOException: Cannot run program "javac"问题,并设置jdk版本
原因:没有配置java路径 解决方法:设置java_home路径 设置jdk版本是10的方法:在sbt文件中添加一行: javacOptions := Seq(") 然后重新执行命令:sbt ...
- [解决]java.io.IOException: Cannot obtain block length for LocatedBlock
在hadoop测试集群运行job的过程中发现部分运行失败,有Cannot obtain block length for LocatedBlock,使用hdfs dfs -cat ${文件}的时候也报 ...
- 解决java.io.IOException: HTTPS hostname wrong: should be
原因:当访问HTTPS的网址.您可能已经安装了服务器证书到您的JRE的keystore .但这个错误是指服务器的名称与证书实际域名不相等.这通常发生在你使用的是非标准网上签发的证书. 解决方法:让JR ...
- SpringBoot之HandlerInterceptor拦截器的使用 ——(三)获取requestBody解决java.io.IOException: Stream closed
原文地址:https://blog.csdn.net/zhibo_lv/article/details/81875705 感谢原作者
- org.apache.tomcat.util.net.NioEndpoint,打开的文件过多
错误信息: 27-Mar-2019 04:20:20.430 严重 [http-nio-8100-Acceptor-0] org.apache.tomcat.util.net.NioEndpoint$ ...
随机推荐
- python3.7的一些心得,不定期更新。
学习的python3.7.2,最新目前是3.8.1 这里记一下主要的几点: pip 是python的模块管理器,姑且这么叫它.和nodejs的npm一样的功能 官网下载python安装包,默认就会按照 ...
- 031.SAP上查看所有的用户账号,查询SAP用户账号的后台数据库表
01. 输入事务代码SU11, 然后输入SAP用户账号数据表USER_ADDR 02. 点击实用程序,再点击内容 03.点击查询 04. 将查看到的结果通过Excel表格导出 不忘初心,如果您认为这篇 ...
- Combobox出现System.Data.DataRowView的原因
这种情况多次遇到.有时候明明完全相同的代码,在不同的场景运行却是两种结果, 其中一种坏的结果就是 comboBox所有的项都显示为System.Data.DataRowView 今天仔研究了一下,应该 ...
- mysql实现ORACLE的connect by prior父子递归查询
oracle中有connect by prior ,可以实现父子递归查询.而mysql中没有这种功能,但我们可以变通实现. 比如一个表: Table Name: tb_Tree Id | Parent ...
- leetcode1302 Deepest Leaves Sum
""" Given a binary tree, return the sum of values of its deepest leaves. Example 1: I ...
- Gerrit部署成功后project下不显示clone地址
gerrit部署成功后使用admin账号登录,在project All-projects下不显示clone地址,新建仓库也不显示. 原因是:默认安装没有安装插件download-commands 安装 ...
- .NET 一次读取几百条数据优化,从原来30分钟优化到30秒
1.全部数据读取到内存, 不要使用string,而是使用stringbuilder,stringbuilder的效率非常高 2.添加到数据库 不要使用excute,而是使用事务,几百万条数据会请求数据 ...
- T_SQL 将一列多行数据合并为一行
SQL Server在进行数据迁移和报表处理的时候会遇到将一列多行数据拼接为一个字符串的情况,为了处理这个问题,在网上找了一些相关的资料,提供两种方法,供遇到类似问题的朋友们参考,也借此加深自己的印象 ...
- SciKit-Learn 教程
本教程力求做到简单易懂.深入浅出,帮助你快速掌握机器学习通用库 SciKit-Learn. 机器学习是计算机科学的一个分支,研究的是无需人类干预,能够自己学习的算法. 与TensorFlow不同,Sc ...
- 面向对象第二个特征-继承(Inheritance)
面向对象第二个特征-继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.java中的继承概述 1>.继承概述 多个类种存在相同属性和行为时,讲这 ...