解决: 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$ ...
随机推荐
- 01 vue入门
vue简介 官网上有介绍,这里粘出来 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心 ...
- Vue(九)---自定义指令(directive )
1.无参数 自定义指令的方式:1. 使用Vue.directive 来自定义2. 第一个参数就是 指令名称 xart3. el 表示当前的html dom对象4. 在方法体内就可以通过 innerHT ...
- 7.1 Varnish VCL
根据以上的配置增加集群,修改default.vcl # This ) # man page for details on VCL syntax and semantics. # # Default b ...
- 你从未见过的Case Study写作指南
Case Study,意为案例分析,Case Study与其它的留学论文作业最大的的差别就在于Case Study在论文开始就需要明确给出论,然后再阐述这个结论的论证依据和理由.留学生们需要知道的是C ...
- TextView标签的属性和跑马灯效果
text:显示的内容 textSize:文本的大小 textColor:文本的颜色 visibility:可见性 默认可见,invisible:表示不可见,但对控件的显示区域做了保留 gone:隐藏 ...
- setup factory 设置自启动
Registry.SetValue(HKEY_LOCAL_MACHINE, "Software//Microsoft//Windows//CurrentVersion//Run", ...
- golang 使用编译选项-H=windowsgui后,仍然输出log到console
大概原理: 略略略... if debug { modkernel32 := syscall.NewLazyDLL("kernel32.dll") procAllocConsole ...
- (win32)解决虚拟按键被输入法截获(转)
源博客地址:http://blog.csdn.net/kencaber/article/details/51417871 响应WM_KEYDOWN消息时发现`~快捷键无效,设置断点发现得到的按键消息根 ...
- 【pwnable.kr】 codemap
pwnable新的一题. download: http://pwnable.kr/bin/codemap.exe ssh codemap@pwnable.kr -p2222 (pw:guest) 这道 ...
- 怎么更改Rstudio中的默认目录
方法一. 每次启动Rstudio之后,执行代码 setwd("F:/R/R_data") 默认目录就会修改为双引号内的位置路径. 方法二. 对Rstudio进行设置一次即可. ①点 ...