以下是我解决Too many open files异常时学习的知识的理解和总结,如有不正确指出,敬请指出!

此问题中文搜索雷同,你可以尝试以下关键字:"file descriptor leak" "stackoverflow" "how to solve open files exception“等。

一下是我的一些总结,或许对您有所帮助!

1.fd
fd is short for file descriptor
在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件,
应用程序就是通过fd识别该文件/设备/服务..
你可能需要自行了解更多fd的定义及功能知识。

2.lsof
linux下的命令, 全称:list system open files
第1节说linux所有资源都是以file形式的,所以这个lsof命令是我们查看系统资源占用情况的得力工具。排查linux下各种资源耗尽,异常
等问题都可以使用它。中文能找到的几乎都是这种http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316599.html,以下为引用:

在终端下输入lsof即可显示系统打开的文件,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充
      地发挥其功能。直接输入lsof部分输出为:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
          init 1 root cwd DIR 8,1 4096 2 /
          init 1 root rtd DIR 8,1 4096 2 /
          init 1 root txt REG 8,1 150584 654127 /sbin/init
          udevd 415 root 0u CHR 1,3 0t0 6254 /dev/null
          udevd 415 root 1u CHR 1,3 0t0 6254 /dev/null
          udevd 415 root 2u CHR 1,3 0t0 6254 /dev/null
          udevd 690 root mem REG 8,1 51736 302589 /lib/x86_64-linux-gnu/libnss_files-2.13.so
          syslogd 1246 syslog 2w REG 8,1 10187 245418 /var/log/auth.log
          syslogd 1246 syslog 3w REG 8,1 10118 245342 /var/log/syslog
          dd 1271 root 0r REG 0,3 0 4026532038 /proc/kmsg
          dd 1271 root 1w FIFO 0,15 0t0 409 /run/klogd/kmsg
          dd 1271 root 2u CHR 1,3 0t0 6254 /dev/null

每行显示一个打开的文件,若不指定条件默认将显示所有进程打开的所有文件。
          lsof输出各列信息的意义如下:
          COMMAND:进程的名称 PID:进程标识符
          USER:进程所有者
          FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等 TYPE:文件类型,如DIR、REG等
          DEVICE:指定磁盘的名称
          SIZE:文件的大小
          NODE:索引节点(文件在磁盘上的标识)
          NAME:打开文件的确切名称

你可能需要自行了解lsof命令使用细节

3. fix too many open files excepiton(POSIX)

a. 网上尤其使用baidu搜出来的答案几乎全是“ulimit -n”查看最大能打开的fd的限制值,通常是 1024(意思是最多能打开1024个),然后
     使用“ulimit -n 4096”调大该限制。这里先下个结论,这个解决方案是碰运气式的,详情且看下面分解。

b. too many open files 出现的原因:

》第1节有说,linux(POSIX)所有存在都是以file形式表示的,所以引起这个异常的原因(几乎)就是你打开了太多‘files’,超过了限制。
         那a中调大限制的方法明显可以用啊。下面这段话给出了不推荐这样做的理由:

摘自http://oroboro.com/file-handle-leaks-server/
            Wrong Answers, Myths and Bad Ideas
            Raise the file handle limit
               One common answer to this problem is to just raise the limit of open file handles and then restart the server every
           day or every few hours.
               This will delay the problem but likely will not fix it. It is possible that your program is not leaking and has a
           legitimate need to hold a large number of file handles. But if your program is designed correctly there usually isn’t
           a need to keep a large number of handles open – even if you have thousands of simultaneous connections. We’ll discuss
           some methods of managing that later.
                If this was a good idea the operating system would already come configured with a higher file descriptor limit. If
           this was necessary, Apache would require you to up this limit before running.

》原因(大多数时候)

The problem is almost certainly that you are leaking file handles. That is, handles are being opened, and after you are
           done with them they are not closed.

Leaked file handles can come from many sources, not just open files. Some common sources are:Sockets,Pipes,Database
           connections,Windows HANDLES,Files.

c. 如何排查及修复(重点)

》当不满足于“ulimit -n 4096”的解决方案,深入想要分析原因时,搜索到的分析方法也大同小异,大多和lsof命令相关,以下罗列一些;

=.To find out PID for mysqld process, enter: pidof mysqld #pidof命令是找出进程的id号,如pidof java找到Java进程的id号
          =.List File Opened By a PID:lsof -p ${pid} #-p 参数是 --pid的意思, 如 lsof -p 10086是打印10086进程的所有open files
              或者 ls /proc/${pid}/fd #和上行一样,查看该进程打开的files
          =.List File Descriptors in Kernel Memory
              sysctl fs.file-nr #结果:fs.file-nr = 2688 0 379264
          => The number of allocated file handles
          => The number of unused-but-allocated file handles
          => The system-wide maximum number of file handles
                 sysctl fs.file-max #结果是能打开的最大files数量
          =.查看某个用户下打开的files: lsof -u jboss
          =.和计数器结合起来,计算打开的文件数量,如:lsof -p 10086|wc -l, ls -alt /etc/10086/fd|wc -l等等。
        这些分析方法大多是利用lsof配合参数和管道命令,或者是统计/proc/${pid}/fd目录,来分析你的目标的openfiles情况。

》困惑

=. lsof -u root |wc -l 结果是2223, 而ulimit -n 结果是1024, 为什么root用户当前的open files还要比limit大? 这个如果不清楚那
              分析就没意义了,因为你就是要解决open file limit问题的,结果root当前运行时就打开了比limit还多的files.
          =. lsof -p 54552|wc -l 结果是658,54552是我java的进程pid, 而ll /proc/54552/fd |wc -l,结果却是358,为什么统计同一个进程当前
              的open files数量却有如此大的差异? 以哪个为准,和ulimit -n的值有有什么关系?
          =. 先解释第2点,lsof will also give you memory mapped .so-files - which technically isn't the same as a file handle the
               application has control over. /proc/<pid>/fd is the measuring point for open file descriptors。 意思是说lsof的结果包含
               memory mapped .so-files,这些在原理上并不是一般的应用程序控制的fd。 而/proc/<pid>/fd目录很好的反映了fd的open情况。
               适当修改下lsof: lsof -p <pid> | grep -v mem | egrep -v '^COMMAND PID' | wc -l,这样就等同于/proc/<pid>/fd下统计情况。
          =. 是第2点的问题引起了第1点?使用lsof -u root |grep -v mem | egrep -v '^COMMAND PID' | wc -l, 结果是 1221,还是大于limit.
              就是说root用户当前open 1221 files是确定定, root 的 files limit是1024也是确定的, 而造成more than limit究竟为何:其实是
              limit这个限制针对的对象,最终找出是这样的:because the limit is on a per-process base and not per-user 。 limit限制是基于
              一个进程而言的(该用户拥有的进程)并非用户。 就是ulimit -n是1024的意思是由root用户执行的某个进程最多只能打开1024个文件,
              并非root总共只能打开1024个。
          =. sysctl fs.file-max 我的结果是379264,这个数字则是kenel内核总共能支持的open files数量。这个是不能改变的。

》解决

=. 至此可以解释为啥放大limit是碰运气式的,毕竟一个process正常情况下同时要打开超过1024个files还是比较少见的。
          =. 如果需分析leak或者查看open fiels的细节, 则应从pid粒度着手,而不要被user迷惑。
                 lsof -p <pid> | grep -v mem | egrep -v '^COMMAND PID'
                 或者对/proc/<pid>/fd 目录分析。
          =. uprize limit
               即使需要扩大limit限制,实际上大多是os上简单的“ulimit -n 4096”是行不通的,操作系统不允许。 以下两种方式供参考
                 Raising the Global Limit。Edit /etc/sysctl.conf and add the following line:fs.file-max = 65536
                                                     Apply the changes with:sudo sysctl -p /etc/sysctl.conf
                 Raising the per-User Limit.
                     &Edit as root the following system configuration file: % sudo vi /etc/security/limits.conf
                     &Modify the values for nuxeo user (we assume here JBOSS is launched with the sytem user "nuxeo")
                               nuxeo soft nofile 4096
                               nuxeo hard nofile 8192
                        If you want to raise the limits for all users you can do instead:
                               * soft nofile 4096
                               * hard nofile 8192
                     &Edit /etc/pam.d/su: sudo vi /etc/pam.d/su
                     &Uncomment the line:
                            session required pam_limits.so
                     &Once you save file, you may need to logout and login again

d.总结

扩大open files数量限制的操作可以起效,但在此之前相比你应该也对为何出错会感兴趣吧,不妨先分析一下喽。

以上总结中的观点是网上各处搜罗及个人理解所得,如有误,请谅解指正。

Too many open files解决方案及原理的更多相关文章

  1. 转发 win7+iis7.5+asp.net下 CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案

    win7+iis7.5+asp.net下 CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NE ...

  2. Zookeeper- Error contacting service. It is probably not running解决方案和原理

    搭建启动Zookeeper集群出现Error contacting service. It is probably not running解决方案和原理 1.关闭防火墙  [root@srv01 bi ...

  3. 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析

    看两个例子,一个是在一个进程里设置另外一个进程中控件的属性.另外一个是在一个进程里获取另外一个进程中控件的属性. 第一个例子 最近,在做一个使用线程控制下载文件的小程序(使用进度条控件显示下载进度)时 ...

  4. (转)win7+iis7.5+asp.net下 CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案

    本文转载自:http://www.cnblogs.com/finesite/archive/2011/01/28/1946940.html 网上搜的解决方案但在我的环境下仍旧没有解决,我的方法如下: ...

  5. CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案

    1 设置c:windows\temp 目录访问权限 temp--> 属性-->安全-- > 添加network service -->并赋予其权限为 读 和 写--> 确 ...

  6. win7+iis7.5+asp.net下 CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案

    http://www.cnblogs.com/finesite/archive/2011/01/28/1946940.html 给C:\Windows\temp 文件夹赋予完全控制权限,如图:

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

    http://marsvaadin.iteye.com/blog/1698924 mina性能测试 http://hi.baidu.com/rendong/item/bb5d2b0e4563c76dd ...

  8. WebApi中跨域请求的解决方案和原理

    跨域请求仅发生在JavaScript发起Ajax请求时,浏览器对请求的限制,通常只允许访问同一个域中的资源,或者目标服务器明确的通知浏览器允许该域访问资源. 那么什么叫跨域的:主机地址或者ip地址或者 ...

  9. Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持

    Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持 1. 设置 document.domain为一致  推荐1 2. Apache 反向代理 推荐1 ...

随机推荐

  1. 【前端阅读】——《程序员思维修炼》摘记&读后感&思维导图

    前言:这是一本介绍如何用脑的书,并从思维的角度(以程序员为例),介绍如何从新手成为专家.作者带领着读者(我)共同经历一次有关认知科学.神经学.学习和行为理论的旅程,探索人类大脑令人 惊奇的工作的机制, ...

  2. Linux禁止Ctrl+Alt+Del重新启动

    方法1:改动/etc/inittab 屏蔽 ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now 或者删除改行内容 保存退出 适用对象:RedHat4.8 ...

  3. python for android : BeautifulSoup 有 bug

    BeautifulSoup 善于网页数据分析 .可是 python for android : BeautifulSoup 有 bug , text = h4.a.text 仅仅能取得 None,因此 ...

  4. XXE攻击

    1.背景 现在很多应用都存在XXE(XML External Entity attack)漏洞,就是xml外部实体攻击,比如facebook,很多XML的解析器默认是含有XXE漏洞的. 2.xml的定 ...

  5. H5网页判断手机横屏或是竖屏

    我们做出来的H5页面在手机端浏览的时候,用户很有可能会产生更换横竖屏的操作,这时如果我们能够判断出横竖屏,就可以更好的优化我们的网页,进而拥有更好的用户体验度.下面是判断横竖屏的代码: window. ...

  6. PHP面向对象——构造函数、析构函数

    在PHP中构造函数和析构函数是固定的,如下: // 构造函数 function __construct([argument1,argument2,...,argumentN]){ /* Class i ...

  7. HDOJ 题目3564 Another LIS(线段树单点更新,LIS)

    Another LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  8. Gradle 介绍

    介绍:Gradle是一种构建工具,它抛弃了基于XML的构建脚本,取而代之的是采用一种基于Groovy的内部领域特定语言.Gradle的设计理念是,所有有用的特性都由Gradle插件提供,一个Gradl ...

  9. 【BZOJ1124】[POI2008]枪战Maf 贪心+思路题

    [BZOJ1124][POI2008]枪战Maf Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开 ...

  10. EasyDSS高性能流媒体服务器前端重构(六)- webpack-dev-server 支持手机端访问

    很多时候,前端开发的页面,不仅要在PC端测试效果, 还要在手机端测试效果. 在开发阶段, 我们以 webpack-dev-server 来启动浏览器, 打开正在开发的页面. webpack-dev-s ...