too many open files 的问题

     近几个月公司我所在组负责的系统一直出现“too  many open files” 错误,报错如下:



因为我们负责的系统是处理公司的一些对接业务,系统中使用了大量的webservice ,和http连接操作,所以一般使用了xfire,axis,httpclient等等远程调用框架,一些遗留的大批老的代码都存在未关闭的情况,网上找了一些原因:

程序经常访问的文件、socket在Linux中都是文件file,httpclient是基于socket进行做的封装,所以系统需要记录每个当前访问file的name、location、access authority等相关信息,这样的一个实体被称为file entry。“open files table”(图中橙色标识)存储这些file entry,以数组的形式线性管理。文件描述符(file descriptor)作为进程到open files table的指针,也就是open files table的下标索引,将每个进程与它所访问的文件关联起来了。 

 

        每个进程中都有一个file descriptor table管理当前进程所访问(open or create)的所有文件,文件描述符关联着open files table中文件的file entry。细节不表,对于open files table能容纳多少file entry。Linux系统配置open files table的文件限制,如果超过配置值,就会拒绝其它文件操作的请求,并抛出Too many open files异常,这种限制有系统级和用户级之分。 

       系统级: 
                系统级设置对所有用户有效。可通过两种方式查看系统最大文件限制 
                1  cat /proc/sys/fs/file-max  
                2  sysctl -a 查看结果中fs.file-max这项的配置数量 
                如果需要增加配置数量就修改/etc/sysctl.conf文件,配置fs.file-max属性,如果属性不存在就添加。 
                配置完成后使用sysctl -p来通知系统启用这项配置
 

       用户级: 
                Linux限制每个登录用户的可连接文件数。可通过  ulimit -n来查看当前有效设置。如果想修改这个值就使用 ulimit -n <setting number> 命令。 

              对于文件描述符增加的比例,资料推荐是以2的幂次为参考。如当前文件描述符数量是1024,可增加到2048,如果不够,可设置到4096,依此类推。 
       在出现Too many open files问题后,首先得找出主要原因。最大的可能是打开的文件或是socket没有正常关闭。为了定位问题是否由Java进程引起,通过Java进程号查看当前进程占用文件描述符情况:  

一 、排查第一步,排查使用HTTPclient框架的对接服务商,例如以下程序:


在关闭一些打开的文件流未进行关闭的情况,代码如下:

private static String outputSingleLine(String s) throws IOException{
		StringBuffer sb = new StringBuffer();
		BufferedReader br = null;
		try{
			br = new BufferedReader(new StringReader(s));
			String line = null;
			while ((line = br.readLine()) != null) {
				sb.append(line.trim().replaceAll("\\t", ""));
			}
		}catch(IOException e){
			throw e;
		}finally{
			if(br!=null){
				br.close();
			}
		}
		return sb.toString();
	}

二,查询linux, 查看系统当前连接数是多少?使用命令ulimit –a查看

[root@server30-116 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 62820
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 262144 (可以看出当前用户可打开数量为262144)
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 62820
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
查看所有进程打开的文件数
 
[root@server30-116 ~]# lsof |wc -l
4672

查看当前用户打开了多少文件句柄:

lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more 
131 24204 
57 24244 
57 24231 
56 24264 
这里我只截取了部分输出信息。其中第一行是打开的文件句柄数,第二行是进程号。执行ps -ef | grep 进程号 可查看进程的详细信息。

查找文件句柄问题的时候,还有一个很实用的程序 lsof,可以很方便看到某个进程开了哪些句柄 :

lsof -p pid

 

某个进程开了几个句柄 :

lsof -p pid |wc -l  

这样可以分析出某个进程打开文件的具体内容,


我们还可以分析,查看当前系统TCP链接处于何种状态的文件数量:

[root@server30-116 ~]# netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n
      1 established)
      1 Foreign
     12 LISTEN
     33 ESTABLISHED
     37 TIME_WAIT
   2266 CLOSE_WAIT
 
查看某进程处于CLOSE_WAIT 的状态(要先查看某进程的ID)
 

 
[root@server30-116 ~]# lsof -np 17185 |grep CLOSE_WAIT |wc -l
2266
 



发现很多打开的TCP连接一直处于等待状态。

让后找打webservice连接的失效时间,设置一小段失效时间,

通过以上基本可以解决一些问题,具体还需有观察一段时间

参考文章:http://zhumeng8337797.blog.163.com/blog/static/1007689142012428104618670/


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要解决"too many open files"的问题,可以从两个方面入手:修改系统配置和从程序层面解决。 首先,我们可以尝试修改系统的配置信息。根据引用所述,Linux系统维护了一个open files table来记录当前打开的文件信息,这个表有一个最大容量限制。如果超过这个限制,系统会拒绝其他文件操作并报错"Too many open files"。因此,我们可以通过修改系统配置来增加open files table的容量。 具体来说,可以通过修改Linux系统的文件描述符限制来提高open files table的容量。可以使用命令ulimit来查看和修改文件描述符限制。首先,使用ulimit -n命令查看当前文件描述符的限制。然后,根据实际需求,可以使用ulimit -n <new_limit>命令将文件描述符限制设置为一个较大的值。 除了修改系统配置,我们还可以从程序层面解决这个问题。引用提到,要复现这个问题通常需要一定的业务量和运行一段时间,才能达到系统的阈值。因此,我们可以通过优化程序的资源管理来避免打开过多的文件。 可以尝试以下几种方法来解决这个问题: 1. 确保在程序中正确关闭所有打开的文件。在程序运行结束或不再需要打开的文件时,及时关闭文件。 2. 使用文件池或缓存来管理文件的打开和关闭。通过维护一个固定大小的文件池,在需要访问文件时,从池中获取可用的文件句柄,使用完毕后将文件句柄放回池中。 3. 优化程序的资源使用。检查程序中是否存在资源泄漏或重复打开文件的情况,及时释放不再使用的资源。 综上所述,要解决"too many open files"的问题,可以通过修改系统配置来增加open files table的容量,以及从程序层面优化资源管理来避免打开过多的文件。这样可以提高系统的稳定性和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值