Too many open files解决方案及原理
以下是我解决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解决方案及原理的更多相关文章
- 转发 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 ...
- Zookeeper- Error contacting service. It is probably not running解决方案和原理
搭建启动Zookeeper集群出现Error contacting service. It is probably not running解决方案和原理 1.关闭防火墙 [root@srv01 bi ...
- 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析
看两个例子,一个是在一个进程里设置另外一个进程中控件的属性.另外一个是在一个进程里获取另外一个进程中控件的属性. 第一个例子 最近,在做一个使用线程控制下载文件的小程序(使用进度条控件显示下载进度)时 ...
- (转)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 网上搜的解决方案但在我的环境下仍旧没有解决,我的方法如下: ...
- CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files 解决方案
1 设置c:windows\temp 目录访问权限 temp--> 属性-->安全-- > 添加network service -->并赋予其权限为 读 和 写--> 确 ...
- 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 文件夹赋予完全控制权限,如图:
- mina高并发短连接导致java.io.IOException: Too many open files解决方案
http://marsvaadin.iteye.com/blog/1698924 mina性能测试 http://hi.baidu.com/rendong/item/bb5d2b0e4563c76dd ...
- WebApi中跨域请求的解决方案和原理
跨域请求仅发生在JavaScript发起Ajax请求时,浏览器对请求的限制,通常只允许访问同一个域中的资源,或者目标服务器明确的通知浏览器允许该域访问资源. 那么什么叫跨域的:主机地址或者ip地址或者 ...
- Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持
Atitit.js跨域解决方案attilax大总结 后台java php c#.net的CORS支持 1. 设置 document.domain为一致 推荐1 2. Apache 反向代理 推荐1 ...
随机推荐
- 2016.8.22 Axure两级下拉框联动的实现
刚学Axure,有些很简单的东西都要弄很久,但是弄出来的总归是很开心的. 参考来自:实现省市县下拉框的三级联动 http://www.woshipm.com/rp/348795.html/commen ...
- 转:Java 自动装箱与拆箱(Autoboxing and unboxing)
转: http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing) ...
- java类中,成员变量赋值第一个进行,其次是静态构造函数,再次是构造函数
如题是结论,如果有人问你Java类的成员初始化顺序和初始化块知识就这样回答他.下面是代码: package com.test; public class TestClass{ // 成员变量赋值第一个 ...
- mpvue上手
对于小程序官方编译器,我也不好说什么,不支持scss,不支持emment,一切来说都是不适应 美团mp:http://mpvue.com/mpvue/ vue官方:https://cn.vuejs.o ...
- 想提升java知识的同学请进
这是我最近在整理的笔记,大家可以看看. https://www.gitbook.com/book/jackal007/java_more/ 如果觉得有问题可以提出,随时修改. 这个笔记是我花了好多时间 ...
- Git 学习之--安装配置GitHub
楼主今天学习了一下Git的使用,而且Androdi studio 下加入了Git插件,成功提交项目到自己Github个人主页 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...
- IOS知识点收集
17 duplicate symbols for architecture armv7s 用cocoapods 的时候出现,这种错误一般是由重复引用库文件引起. 原因:自己尝试添加Reachabil ...
- 用递归法将一个整数n转换成字符串。
用递归法将一个整数n转换成字符串. 比如,输入483,应输出字符串"483".n的位数不确定,能够是随意位数的整数. #include "stdafx.h" # ...
- 软件工程第3次作业——Visual Studio 2017下针对代码覆盖率的C/C++单元测试
本项目Github地址(同时包括两个作业项目): Assignment03 -- https://github.com/Oberon-Zheng/SoftwareEngineeringAssignme ...
- 初识python轻量web框架flask
1.使用pip安装Python包 大多数Python包都使用pip实用工具安装,使用pyvenv创建的虚拟环境会自动安装pip. 1.使用pip安装Flask(其它Python包同理) pip ins ...