解决: 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$ ...
随机推荐
- 139. Word Break 以及 140.Word Break II
139. Word Break Given a non-empty string s and a dictionary wordDict containing a list of non-empty ...
- 7.7 Varnishadm命令
- java代码静态分析工具
需求:有些基础类型的遍历,值希望它被赋予指定的几个值,赋予其他值能够别编译器(IDEA/eclipse)提醒 Android studu结合自己的插件,引入 <!-- https://mvnre ...
- SPI协议解析
1. SPI物理层 SPI通讯需要使用4条线:3条总线和1条片选 . SPI遵循主从模式,3条总线分别是SCK.MOSI和MISO,片选线为nSS(低电平有效),SPI协议适用于一主多从的工作场景: ...
- Codeforces 448C:Painting Fence 刷栅栏 超级好玩的一道题目
C. Painting Fence time limit per test 1 second memory limit per test 512 megabytes input standard in ...
- 指令——mkdir
一个完整的指令的标准格式: Linux通用的格式——#指令主体(空格) [选项](空格) [操作对象] 一个指令可以包含多个选项,操作对象也可以是多个 指令mkdir——(make directory ...
- 杂记 -- 关于ref、kepp-alive、nextTick、fetch
1.ref:定义一个普通的dom节点或一个vue的组件实例对象 定义方法: <div class="page1"> <button @click="li ...
- servlet中urlpatterns注意事项
在servlet中, @WebServlet(urlPatterns="/newsAdd")接收 resp.sendRedirect("/wedding/houtai/N ...
- 038-PHP向返回的闭包函数实例中,传递外部变量参数
<?php # 向返回的闭包函数实例中,传递外部变量参数 # 直接调用将不会输出$txt的内容 function demo(){ $txt = '我爱PHP'; # 1.function()内的 ...
- 【转】JS字符(字母)与ASCII码转换方法
var strVariable; for(var i=0;i<25;i++) { console.log(String.fromCharCode((65+i))); } strVariable. ...