开发案例——文件句柄数过多

6 篇文章 0 订阅

 

问题描述:使用 lsof 查看 java 进程(tomcat)的文件句柄数过多,并且持续增加而未见减少。

定位方法:1.使用 lsof 查看详细的句柄信息,发现存在大量的“pipe”和“eventpoll”(占总句柄数的80%以上),如图:

     2.基本可以确定是由于代码中存在打开文件/创建连接后未进行释放/销毁导致;但由于tomcat中部署模块较多代码量巨大,日志文件内容也很多很难从中找出有意义的信息(文件句柄数超出系统限制后,会刷出很多连接异常、文件无法访问异常,这些信息会掩盖掉真正出问题的地方),需要先定位到具体模块才好进行进一步的代码审查(否则代码审查的工作耗时太长)。

3.将各模块分开部署到不同的机器,并确保复现条件(确保正常操作,以及人为制造后期断线等异常情况),逐步缩小范围。
比如:共A,B,C,D,E,F,G,H八个模块
① 首先将A,B,C,D部署于1号机器、E,F,G,H部署于2号机器;若1号没问题,2号出问题,则可确定出问题的模块是在E,F,G,H中;
② 然后将A,B,C,D,E,F部署于1号机器、G,H部署于2号机器;若1号出问题了,2号没问题,则可确定出问题的模块是在E,F两个模块中;
③ 将 A,B,C,D,E,G,H 部署于1号机器、F部署于2号机器;若1号没问题,2号出问题了,则最终可确定出问题的模块是F模块。

(注意:这里如果两台机器都同时发现问题,则说明多个模块都存在问题,应当打乱顺序重新测试,应当找出是具体是哪些模块存在问题(或者说找出无问题的模块);多个模块均存在问题时,应当考虑是否这些模块中引入的基础库中存在问题,或者找出其它共性。)

针对F模块进行代码审查,发现该模块中存在一个重连任务,在 startup() 出现异常时,会导致 shutdown() 未执行;并且重连之前的连接也未进行释放(关闭操作)。

 继续查看 startup(), shutdown() 的代码,发现在 startup() 中不存在异常处理的代码,也就是说,如果 connector.connect(...), connFuture.getSession() 出现异常,会导致 connector, connFuture 未释放。

 

问题解决:

本案例修改建议:

  1. 在 startup() 内创建连接对象前判断是否已存在连接并判断是否连接正常;若正常则直接返回,若不正常则应当释放之前的连接;
  2. 在 startup() 内需添加异常处理,若connect(), getSession() 出现异常,则应当释放之前的连接;

 

注意,文件句柄过多的问题并不仅限于NIO网络连接,有可能出现问题的有:

  1. 打开文件未释放
  2. 打开管道未释放
  3. 建立网络连接未释放(pipe,eventpoll多出现在 NIO 网络编程未释放资源 —— selector.close())
  4. 创建进程调用命令未释放(Runtime.exe(...) 得到的 Process, InputStream, OutputStream 未关闭,这也会导致 pipe,eventpoll 未释放)
  5. mina库使用NIO时未使用connector.dispose();
  6. netty3库使用NIO时未使用bootstrap.shutdown() 或bootstrap.releaseExternalResources();

netty4使用NIO时未使用 eventLoopGroup.shutdownGracefully();

 

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Linux服务器中,文件句柄是内核用来管理文件的一个重要资源。当我们要处理大量的文件时,我们需要知道当前系统的文件句柄,便于优化系统性能和管理文件。那么,如何查看当前服务器文件句柄呢? 方法一:使用lsof命令 lsof命令在Linux服务器中十分常用,它可以查看系统当前打开的文件列表。通过使用该命令,我们可以查看当前所有打开的文件量,从而得知系统文件句柄。具体操作如下: 1.打开终端,输入以下命令: lsof | wc -l 2.回车后,就能看到当前系统的文件句柄。 方法二:使用cat命令 cat命令可以显示文件内容,也可以显示一些系统文件的信息。我们可以通过cat命令查看/proc/sys/fs/file-max文件中定义的最大文件打开,从而得知当前系统文件句柄。具体操作如下: 1.打开终端,输入以下命令: cat /proc/sys/fs/file-max 2.回车后,就能看到当前系统的最大文件打开。 3.如果要查看当前已打开的文件量,可以输入以下命令: cat /proc/sys/fs/file-nr | awk '{ print $1 }' 4.回车后,就能看到当前已打开的文件量。 综上所述,使用lsof和cat命令都可以查看Linux服务器的文件句柄。从以上两种方法可以看出,文件句柄是一个十分重要的资源。管理好文件句柄,可以让我们更好地了解服务器的运行情况,并优化服务器性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值