分享好友 最新动态首页 最新动态分类 切换频道
java.io.IOException: Too many open files问题
2024-12-26 21:01

在开发linux在线服务器的时候经常会遇会句柄泄露的问题。因为在linux系统设计里面遵循一切都是文件的原则,即磁盘文件、目录、网络套接字、磁盘、管道等,所有这些都是文件,在我们进行打开的时候会返回一个fd,即是文件句柄。如果频繁的打开文件,或者打开网络套接字而忘记释放就会有句柄泄露的现象。在linux系统中对进程可以调用的文件句柄数进行了限制,在默认情况下每个进程可以调用的最大句柄数是1024个,如果超过了这个限制,进程将无法获取新的句柄,而从导致不能打开新的文件或者网络套接字,对于线上服务器即会出现服务被拒绝的情况。

查看句柄

在linux系统中可以通过ulimit–n查看每个进程限制的最大句柄数,通过ulimit –HSn 10240修改进程的最大句柄数。当句柄数目达到限制后,就回出现”too many files open”。

查看进程占用的句柄数有几种办法

1) 通过cat/proc/pid/fd可以查看线程pid号打开的线程,cat   /proc/pid/fd |wc -l

2) 通过lsof命令,需要root账号权限

查看当前系统的打开文件数

# lsof | wc -l  

# watch "lsof | wc -l"

可以用lsof -p <pid of process>看打开的文件句柄数.查看某个进程的打开文件数

#lsof -p  1234|wc -l

 

查看Linux系统打开的文件句柄数

# lsof -n | awk '{print $2}'| sort | uniq -c | sort -nr 

   3009 31312
     15 7364
     14 8002
     14 7777
     14 7382
     14 665
     14 6308
     ...
第一列:进程打开的文件句柄数
第二列:PID

 

应用日志报java.io.IOException: Too many open files

打开的文件过多,一般来说是由于应用程序对资源使用不当造成,比如没有及时关闭Socket或数据库连接等。但也可能应用确实需要打开比较多的文件句柄,而系统本身的设置限制了这一数量。

 

异常 1 
java.net.SocketException: Too many open files

    at java.net.PlainSocketImpl.accept(Compiled Code)
    at java.net.ServerSocket.implAccept(Compiled Code)
    at java.net.ServerSocket.accept(Compiled Code)
    at weblogic.t3.srvr.ListenThread.run(Compiled Code)

异常 2
java.io.IOException:打开的文件过多

    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:54)
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:54)
    at java.lang.Runtime.execInternal(Native Method)
    at java.lang.Runtime.exec(Runtime.java:551)
    at java.lang.Runtime.exec(Runtime.java:477)
    at java.lang.Runtime.exec(Runtime.java:443)

...

第一个异常在错误影响到基础 TCP 协议时抛出,而第二个异常则在错误影响到 I/O 操作时抛出,这个是由于交换分区不足造成的。

文件打开数过多最坏的情况可以使系统崩溃,到时候只能是重起服务器了。 

 

原因:  

 1、大多数情况是程序没有正常关闭一些资源引起的,所以出现这种情况,请检查io读写,socket通讯等是否正常关闭。

  操作系统的中打开文件的最大句柄数受限所致常常发生在很多个并发用户访问服务器的时候。因为为了执行每个用户的应用服务器都要加载很多文件(new一个socket就需要一个文件句柄),这就会导致打开文件的句柄的缺乏。 

       主要方向:在源码项目中查找所有引用了InputStream或者其他流的地方,查看其是否在使用完后,正常close掉,此处建议将流的close放到finally块中,这样异常时也会去close流。

       次要方向:session或者其他有用到socket的代码处,仔细查询看是否有没有释放资源的地方

 
   2、 如果检查程序没有问题,那就有可能是linux默认的open files值太小,不能满足当前程序默认值的要求,比如数据库连接池的个数,tomcat请求连接的个数等。。。 

         限制:有时是linux系统的参数的限制,需要修改内核参数。有时是中间件(weblogic、nginx)中启动文件参数限制,尤其是默认1024,在修改linux后若中间件有涉及也要同步修改。

      

 

解决:

尽量把类打成jar包,因为一个jar包只消耗一个文件句柄,如果不打包,一个类就消耗一个文件句柄.
java的垃圾回收不能关闭网络连接打开的文件句柄,如果没有执行close()(例如:java.net.Socket.close())则文件句柄将一直存在,而不能被关闭.你也可以考虑设置socket的最大打开数来控制这个问题.
对操作系统做相关的设置,增加最大文件句柄数量。


Linux
在 Linux内核2.4.x中需要修改源代码,然后重新编译内核才生效。编辑Linux内核源代码中的 include/linux/fs.h文件,将 NR_FILE 由8192改为65536,将NR_RESERVED_FILES 由10 改为 128。编辑fs/inode.c 文件将MAX_INODE 由16384改为262144。或者编辑 /etc/sysctl.conf  文件增加两行 fs.file-max = 65536 和 fs.inode-max = 262144 。一般情况下,系统最大打开文件数比较合理的设置为每4M物理内存256,比如256M.

 

在linux下的fd是有限制的,一个是系统的限制,一个是用户进程限制。

 

服务器端修改

查看系统允许打开的最大文件数

#cat /proc/sys/fs/file-max

sysctl fs.file-max=655360可以调整内核的阈值,前提得有root权限。可参考/etc/sysctl.conf,用man sysctl.conf命令sysctl -a可以显示所有的能够调整参数。

 

查看每个用户允许打开的最大文件数

ulimit -a

发现系统默认的是open files (-n) 1024,问题就出现在这里。

在系统文件/etc/security/limits.conf中修改这个数量限制

在文件中加入内容

* soft nofile 65536
* hard nofile 65536

 

另外方法
1.使用ps -ef |grep java   (java代表你程序,查看你程序进程) 查看你的进程ID,记录ID号,假设进程ID为12
2.使用:lsof -p 12 | wc -l    查看当前进程id为12的 文件操作状况
    执行该命令出现文件使用情况为 1052
3.使用命令:ulimit -a   查看每个用户允许打开的最大文件数
    发现系统默认的是open files (-n) 1024,问题就出现在这里。
4.然后执行:ulimit -n 4096
     将open files (-n) 1024 设置成open files (-n) 4096

这样就增大了用户允许打开的最大文件数

 

同时查看ulimit实际是否生效,如果设置了但并未生效也不行。

运维实战案例之“Too many open files”错误与解决方法 

此文中就介绍了设置了参数,但并未生效引起的。

 

 

socket未关闭现象

1. 首先用lsof -p PID 查看一下打开文件的列表如果出现下图状况基本就两种可能,stream未关闭或者socket未关闭,出现can't identify protocol字样

2. 用netstat -anp | grep PID查看端口占用情况,若出现下图情况,证明Socket未关闭

原因

  是因为Socket协议本身,若正确关闭一个Socket需要往返消息4次,若中途有未接到的消息就会停留在某个状态下,比如当前的CLOSE_WAIT。

        如果close_wait状态过多,可能是socket未关闭引起。

解决办法

  客户端:主动关闭任何一个socket,尽量在finally中加入socket.close()语句。

  服务器:设置读取超时时间如:socket.setSoTimeout(3000);其次在用完之后主动关闭,做法同客户端方式。同时在任何的异常加入socket.shutdownInput();socket.shutdownOutput();

 

问题定位

问题定位步骤
1、   用root帐户 遍历 /proc/进程ID/fd目录,若该目录下文件数较大(如果大于10一般就属于socket泄漏,根据该进程ID,可以确认该进程ID所对应的名称。
2、   重启程序恢复服务,以便后续查找问题。
3、   strace 该程序并记录strace信息。strace –p 进程ID >>/tmp/stracelog.log 2>&1
4、   查看 /proc/进程ID/fd 下的文件数目是否有增加,如果发现有增加,记录上一个socket编号,停止strace
5、   确认问题代码的位置。打开/tmp/stracelog.log,从尾部向上查找close(socket编号)所在行,可以确认在该次close后再次创建的socket没有关闭,根据socket连接的server ip可以确认问题代码的位置。


另一种方法:判断是否有socket泄漏:
lsof | grep "can't identify protocol"
如果存在很多,则代表socket泄漏,同时会显示哪个进程使用的sock未关闭。

 

文件句柄泄露定位方法

1、使用lsof命令查出有哪些文件或者socket被打开。

2、根据文件名找到相应的模块,检查相关的代码.如果是socket,则根据端口号找到相应的模块,最后检查相关的代码。

 

 

 


 

mina高并发短连接导致java.io.IOException: Too many open files解决方案

  1.         //设置超时   
  2.         connector.setConnectTimeoutMillis(defaultConnectTimeOut);  
  3.         ConnectFuture connectFuture = connector.connect(address);  
  4.         connectFuture.awaitUninterruptibly();   //同步,等待,直到连接完成   
  5.         if  (connectFuture.isDone()) {  
  6.             if  (!connectFuture.isConnected()) {  //若在指定时间内没连接成功,则抛出异常   
  7.                 logger.info("fail to connect "  + logInfo);  
  8.   
  9.                 throw   new  Exception();  
  10.             }  
  11.         }  

 

         经过分析导致主机文件句柄泄露的原因为,客户端发起服务端连接时,会请求系统分配相关的文件句柄,在原代码中,仅仅判断是否连接成功,而未对连接失败进 行资源释放,从而造成文件句柄泄露。当总的文件句柄数超过系统设置值(ulimit -n 查看同一个进程允许的最大文件句柄数,则抛出异常“java.io.IOException: Too many open files",导致无法创建新的连接,服务器挂掉。

      更改后的代码如下

 

Java代码  

  1. final  NioSocketConnector connector =  new  NioSocketConnector();  
  2.         final  String[] result =  new  String[ 1 ];  
  3.         connector.getFilterChain().addLast("codec" ,  
  4.                 new  ProtocolCodecFilter( new  ObjectSerializationCodecFactory()));  
  5.         connector.setHandler(handler);  
  6.   
  7.         //设置超时   
  8.         connector.setConnectTimeoutMillis(defaultConnectTimeOut);  
  9.         ConnectFuture connectFuture = connector.connect(address);  
  10.         connectFuture.awaitUninterruptibly();   //同步,等待,直到连接完成   
  11.         if  (connectFuture.isDone()) {  
  12.             if  (!connectFuture.isConnected()) {  //若在指定时间内没连接成功,则抛出异常   
  13.                 logger.info("fail to connect "  + logInfo);  
  14.                 connector.dispose();    //不关闭的话会运行一段时间后抛出,too many open files异常,导致无法连接   
  15.   
  16.                 throw   new  Exception();  
  17.             }  
  18.         }  

 


 

from http://www.jianshu.com/p/2e6748c4c0b7

 

原因一:Linux 的open files 数不够

 

原因二:TCP 参数配置不对

常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭
服务器保持了大量TIME_WAIT状态

配置生效后,观察结果,TIME_WAIT 明显减少。

原因三:Tomcat 配置不对

connectionTimeout - 网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。
当前配置connectionTimeout=0

根据公式:服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

待测试验证

 

原因四:程序打开了许多文件,但未关闭连接

之前一直在找程序哪里打开了文件却未关闭连接,未果。
才想到连接打开后,多久可以关闭。

待解决的问题是
)如何定位到程序代码什么地方打开了文件
)打开的这些文件是不是都是必要的
)can't identify protocol的原因

 

 

参考资料

1、http://www.2cto.com/kf/201212/175863.html

2、http://marsvaadin.iteye.com/blog/1698924

3、MINA2 错误解决方法-- Linux下tomcat报错“java.net.SocketException: Too many open files”

4、tcp socket文件句柄泄漏

最新文章
驻马店楼市|驻马店平均房价怎么样?人气好房有哪些?
众所周知,房价是一个牵扯到国计民生的大问题,而在过去,很多朋友都因为驻马店等城市高居不下的房价所苦恼,因为没房,所以很多事情就干不成,比如说结婚,有时候房子就是一个硬性的要求。那么如今驻马店的房价还贵吗?不瞒您说,咱不说便
淘宝小类目如何选关键词?掌握这些!
  关键词对于标题优化和推广都很重要,但是有一些卖家朋友还是选不出优质的关键词,所以我们今天的重点在于关键词的选择,下面重点说下咱们关键词怎么选择,而且这个是可以使用到我们其他小类目中的奥!  1.关键词特点  常规的推广,
阿里巴巴组织实践:阿里文化与领导力演进
《阿里巴巴组织实践:阿里文化与领导力演进》塑造数智企业的组织核心竞争力主讲:余星冰老师【课程背景】本培训课程将以亲历者的视角、时间线的主轴、穿插关键事件回顾的方式,介绍阿里巴巴的企业文化与领导力伴随业务发展、助力业务拿结果
Pandas入门学习总结
import pandas as pd import numpy as np # Pandas中的数据结构 # Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近, # 其区别是:List中的元素可以是不同的数据类型,
阿维塔11能在泰国高端电动SUV市场脱颖而出?
2024年12月,阿维塔11在泰国正式开启预订,作为阿维塔品牌的旗舰电动SUV,阿维塔11的上市备受关注。据了解,此次推出的阿维塔11共有两款时尚版本,预定价格分别为209.9万泰铢和229.9万泰铢,预计将成为电动SUV市场中的新亮点。时尚设计与前
消息称小米新款折叠屏手机下月登场,预计为 MIX Fold 3
7 月 14 日消息,随着铰链技术的发展,“轻薄”已经取代“折痕”成为厂商对折叠屏手机的主攻方向。据数码博主 @数码闲聊站 今日爆料,。网友在评论区询问小米 MIX Fold 3 的影像配置,该博主回复 “徕卡全焦段四摄”,间接透露了文中所提机
解读微信公众平台公众号排名十大规则
首先,谈谈我对微信公众号的理解,用一句话来概要就是:用户订阅我们的微信公众号,只想解决他们的问题,解决了用户的问题,你的公众号,就静静的留在了他们的微信通讯录里。  我们在微信上面搜索关键词查找公众账号的时候,会看到有的公
构建高效专业主机销售,打造销售新攻略
构建专业卖主机的,需从用户需求出发,优化产品展示、简化购买流程,并利用数据分析营销。结合SEO优化、社交媒体推广,打造高效销售,实现品牌与用户的双赢。- [明确目标用户群体](#id1)- [选择合适的建站](#id2)- [设计界面](#id3)- [优化
网站运营外链怎么做
在当今的互联网时代,网站运营的关键手段之一就是外部链接(简称外链)。外链不仅是提高网站权重、增加流量的重要途径,也是提升网站知名度和用户体验的有效方式。本文将详细介绍如何进行网站运营外链的搭建与管理。外链的基本概念与作用外
青柑普洱茶的功效作用可以减肥吗-减肥茶排行榜第一名
青柑普洱茶是一种常见的普洱茶,有着特别的功效和作用。多人喝普洱茶是为了减肥,故此咱们来探讨一下青柑普洱茶对减肥是不是有效。青柑普洱茶是一种低热量的饮料,一杯普洱茶的热量一般只有2-3卡路里,相比于其他高糖饮料,这个热量非常低
相关文章
推荐文章
发表评论
0评