- 浏览: 193091 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
dabing69221:
感谢
linux下安装和配置memcached,以及java操作的示例代码 -
dabing69221:
楼主,写的不错,学习了
linux下安装和配置memcached,以及java操作的示例代码 -
jpsb:
...
Eclipse 保存文件时自动格式化代码 -
lwj1113:
非常感谢
通过WSC的工具来生成SalesForce的WSDL文件描述对象和方法 -
alajl:
写的好,分析过程也能详尽,对于我碰到的问题,很有建设性的帮助
Java NIO类库Selector机制解析(Too many open files 和 No buffer space available)
MINA2 错误解决方法-- Linux下tomcat报错“java.net.SocketException: Too many open files”
- 博客分类:
- Tomcat
部署到linux下的tomcat,今天发现包了“java.net.SocketException: Too many open files”,以前从来没有遇到过,在此记录一下:
彻底解决问题的是第三步, 所以,可以直接跳到第三步去看解决方法和步骤,当日第一、第二步是我不断探索,尝试解决问题的过程,虽然没有找到点上,但是还是有些意义的,因为linux切实有打开资源数量的限制,肯定需要修改的。
异常信息:
原因:
linux下有有文件限制,结果文件数操作最大限制,导致程序异常:问题是程序中有个静态方法打开文件时忘记关闭。两种解决方法,一是设置linux的最大文件打开数量(无法根本解决问题),二是解决程序中的bugs,即消除有问题的代码。
第一次解决
解决:
方法一、增大系统打开文件的数量(无法根本解决问题)、
1、默认linux同时最大打开文件数量为1024个,用命令查看如下:ulimit -a:查看系统上受限资源的设置(open files (-n) 1024):
2、可以修改同时打开文件的最大数基本可以解决:ulimit -n 4096
已经修改了最大打开文件数。
方法二、修改程序中的bugs:
程序中有个静态的方法打开文件后,没有关闭文件,导致每次请求都会去打开文件,在程序中填入关闭输入流的操作即可以:
问题彻底解决
-----
第二次解决:
实际测试后发现这个问题还没有解决,最终又找了些方法,经过一段时间的测试,似乎解决了问题:
具体步骤如下:
linux为redhat服务器版本(非个人版),必须设置的内容:
1、/etc/pam.d/login 添加
# 注意看这个文件的注释
具体文件的内容为:
修改后的内容:
2. /etc/security/limits.conf 添加
root 是一个用户,如果是想所有用户生效的话换成 * ,设置的数值与硬件配置有关,别设置太大了。
修改前内容
修改后的内容
3. 修改 /etc/rc.local 添加
修改前内容
修改后内容
做完3个步骤,就可以了。
**************************************
补充说明:
/proc/sys/fs/file-max
该文件指定了可以分配的文件句柄的最大数目。如果用户得到的错误消息声明由于打开文件数已经达到了最大值,从而他们不能打开更多文件,则可能需要增加该值。可将这个值设置成有任意多个文件,并且能通过将一个新数字值写入该文件来更改该值。
缺省设置:4096
/proc/sys/fs/file-nr
该文件与 file-max 相关,它有三个值:
已分配文件句柄的数目
已使用文件句柄的数目
文件句柄的最大数目
该文件是只读的,仅用于显示信息。
关于“打开文件数”限制
Linux系统上对每一个用户可使用的系统资源都是有限制的,这是多用户系统必然要采用的一种资源管理手段,试想假如没有这种机制,那么任何一个普通用户写一个死循环程序,用不了多久系统就要“拒绝服务”了。
今天我遇到了tomcat日志报的错误信息”too many open files”,第一意识就想到了是ulimit控制的”open files“限制。然而问题来了。我在/etc/profile里加入了 ulimit -n 4096保存之后,普通用户登录的时候均会收到一条错误信息ulimit: open files: cannot modify limit: Operation not permitted。然后普通用户的open files限制还是默认值1024。
然后开始在互联网上搜索关于ulimit的信息。互联网果然方便,信息铺天盖地。大家也可以搜一下试一下。其中我了解到两个以前不知道的相关内容。
第一个是内核参数 fs.file-max ,影射为 /proc/sys/fs/file-max
第二个是配置文件 /etc/security/limits.conf
其中大部分的信息中提到 将 /proc/sys/fs/file-max的值设置为4096和ulimit -n 4096是相同的效果。对此我很怀疑,为什么呢?首先ulimit 是一个普通用户也可以使用的命令,而fs.file-max只有root有权设置。其次,很明显fs.file-max是一个全局的设置,而ulimit 是一个局部的设置,很明显的是不相同的。
带着疑虑,又在网上搜索了许久,未果(实际上是我搜索的关键字不够准确)。
最后终于在内核文档/usr/src/linux/Documentation/sysctl/fs.txt里找到下面一段话:
file-max & file-nr:
The kernel allocates file handles dynamically, but as yet it doesn’t free them again. The value in file-max denotes the maximum number of file-handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit.
The three values in file-nr denote the number of allocated file handles, the number of unused file handles and the maximum number of file handles. When the allocated file handles come close to the maximum, but the number of unused file handles is significantly greater than 0, you’ve encountered a peak in your usage of file handles and you don’t need to increase the maximum.
这两段话的大致意思是:
内核动态地分配和释放“file handles”(句柄)。file-max的值是内核所能分配到的最大句柄数。当你收到大量关于句柄用完的错误信息时,你可以需要增加这个值以打破老的限制。
file-nr中的三个值的含意分别是:系统已经分配出去(正在使用)的句柄数,没有用到的句柄数和所有分配到的最大句柄数。当分配出去的句柄数接近 最大句柄数,而“无用的句柄数”大于零时,表明你遇到了一个“句柄”使用高峰,这意为着你不需要增加file-max的值。
看完这段话,相信大家都明白了。file-max是系统全局的可用句柄数。根据我后来又翻查的信息,以及对多个系统的查看求证,这个参数的默认值是跟内存大小有关系的,增加物理内存以后重启机器,这个值会增大。大约1G内存10万个句柄的线性关系。
再回过头来看这两段话,不知道你意识到了没有,文中只提到了file-max的增加,而没有提到了该值的减少。那些在操作ulimit时同时操 作了file-max的哥们儿,估计无一例外地将file-max设置成了4096或者2048。但以似乎也没有因此而导致系统无法打开文件或者建议连 接。(实际上,我将file-max的值设备成256,然后使用shell编写用vi打开500个文件角本运行,并没有得到任何错误信息,查看file- nr的值,系统当前分配的句柄值已经远超过了后面的最大值。所以我猜想对于file-max的任何减少的操作都是毫无意义的,姑且不去管他。实践中需要减 少file-max的时候总是不多见的。 )实事证明我犯了一个致命的错误。我测试的时候使用的是root用户,而当我再次使用普通用户测试的时候,预料中的错误信息出现了:”Too many open files in system”。可见,file-max的减少对系统也是影响力的。前面的结论“所以我猜想对于file-max的任何减少的操作都是毫无意义的”是错误 的。
然后便是/etc/security/limits.conf文件,这个文件很简单,一看就能明白。
于是我按照注释中描述的格式两个两行:
* soft nofile 4096
* hard nofile 4096
恐怖的是,网上居然有人说改了这个设置是需要重启系统的!实在是让人想不通啊,鼎鼎大名的UNIX系统,怎么可能因为这么小小的一个改动就需要 重启系统呢?结果当我再次以普通用户登录的时候,那个”ulimit: open files: cannot modify limit: Operation not permitted”提示没有了,查看ulimit -n,果然已经变成了4096。
linux lsof 修改句柄限制(转)
在Linux下,我们使用ulimit -n 命令可以看到单个进程能够打开的最大文件句柄数量(socket连接也算在里面)。系统默认值1024。
对于一般的应用来说(象Apache、系统进程)1024完全足够使用。但是如何象squid、mysql、java等单进程处理大量请求的应用来说就有点捉襟见肘了。如果单个进程打开的文件句柄数量超过了系统定义的值,就会提到“too many files open”的错误提示。如何知道当前进程打开了多少个文件句柄呢?下面一段小脚本可以帮你查看:
lsof -n |awk ‘{print $2}’|sort|uniq -c |sort -nr|more
在系统访问高峰时间以root用户执行上面的脚本,可能出现的结果如下:
# lsof -n|awk ‘{print $2}’|sort|uniq -c |sort -nr|more
131 24204
57 24244
57 24231
56 24264
其中第一行是打开的文件句柄数量,第二行是进程号。得到进程号后,我们可以通过ps命令得到进程的详细内容。
ps -aef|grep 24204
mysql 24204 24162 99 16:15 ? 00:24:25 /usr/sbin/mysqld
哦,原来是mysql进程打开最多文件句柄数量。但是他目前只打开了131个文件句柄数量,远远底于系统默认值1024。
但是如果系统并发特别大,尤其是squid服务器,很有可能会超过1024。这时候就必须要调整系统参数,以适应应用变化。Linux有硬性限制和软性限制。可以通过ulimit来设定这两个参数。方法如下,以root用户运行以下命令:
ulimit -HSn 4096
以上命令中,H指定了硬性大小,S指定了软性大小,n表示设定单个进程最大的打开文件句柄数量。个人觉得最好不要超过4096,毕竟打开的文件句柄数越多响应时间肯定会越慢。设定句柄数量后,系统重启后,又会恢复默认值。如果想永久保存下来,可以修改.bash_profile文件,可以修改 /etc/profile 把上面命令加到最后。
仍未处理的问题:
为什么redhat9的个人版按照以上的方式修改1024tcp连接限制依然不行呢?
是因为个人版最多支持1024个tcp连接,还是修改方式、相关文件会有所不同?
以上内容,来源网络并加自己亲自测试,经过测试,似乎没有再出现过问题,但不知道是否真的解决,有待更长时间的测试看看
第三次解决--还解决不了,就彻底无语了(经过压力测试,运行7天再也没有出现该问题)
问题的原因是:原来的MINA2程序之关了IoSession,并没有关闭IoConnector实例,但恰恰就是因为没有关闭每次打开的IoConnector实例,造成了"Too many open files ".
原来的程序:
修改后的程序
用完后一定要释放资源:
同时在配置文件 /etc/security/limits.conf 加了一个配置(该不该问题不大):
# kevin.xie added, fixed 'too many open file' bug', 2012-01-04
* soft nofile 65536
* hard nofile 65536
能帮助到你,感到很开心
彻底解决问题的是第三步, 所以,可以直接跳到第三步去看解决方法和步骤,当日第一、第二步是我不断探索,尝试解决问题的过程,虽然没有找到点上,但是还是有些意义的,因为linux切实有打开资源数量的限制,肯定需要修改的。
异常信息:
............ Oct 17, 2011 5:22:41 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run SEVERE: Socket accept failed java.net.SocketException: Too many open files at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375) at java.net.ServerSocket.implAccept(ServerSocket.java:470) at java.net.ServerSocket.accept(ServerSocket.java:438) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210) at java.lang.Thread.run(Thread.java:636) Oct 17, 2011 5:22:43 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run SEVERE: Socket accept failed java.net.SocketException: Too many open files at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375) at java.net.ServerSocket.implAccept(ServerSocket.java:470) at java.net.ServerSocket.accept(ServerSocket.java:438) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210) at java.lang.Thread.run(Thread.java:636) Oct 17, 2011 5:22:44 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run SEVERE: Socket accept failed java.net.SocketException: Too many open files at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375) at java.net.ServerSocket.implAccept(ServerSocket.java:470) at java.net.ServerSocket.accept(ServerSocket.java:438) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:59) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:210) at java.lang.Thread.run(Thread.java:636) ............
原因:
linux下有有文件限制,结果文件数操作最大限制,导致程序异常:问题是程序中有个静态方法打开文件时忘记关闭。两种解决方法,一是设置linux的最大文件打开数量(无法根本解决问题),二是解决程序中的bugs,即消除有问题的代码。
第一次解决
解决:
方法一、增大系统打开文件的数量(无法根本解决问题)、
1、默认linux同时最大打开文件数量为1024个,用命令查看如下:ulimit -a:查看系统上受限资源的设置(open files (-n) 1024):
[root@**** bin]# 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) 16384 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 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) 16384 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [root@**** bin]#
2、可以修改同时打开文件的最大数基本可以解决:ulimit -n 4096
[root@**** bin]# ulimit -n 4096 [root@**** bin]# 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) 16384 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 4096 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) 16384 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [root@**** bin]#
已经修改了最大打开文件数。
方法二、修改程序中的bugs:
程序中有个静态的方法打开文件后,没有关闭文件,导致每次请求都会去打开文件,在程序中填入关闭输入流的操作即可以:
public static List<GpsPoint> getArrayList() throws IOException { List<GpsPoint> pointList = null; // 读取配置文件 InputStream in = ParseGpsFile.class.getClassLoader().getResourceAsStream("GPS1.TXT"); // 读路径出错,换另一种方式读取配置文件 if (null == in) { System.out.println("读取文件失败"); return pointList; } pointList = new ArrayList<GpsPoint>(); try { BufferedReader br = new BufferedReader(new InputStreamReader(in)); String longtude = ""; String latude = ""; String elevation = ""; while ((longtude = br.readLine()) != null) { // 读下一行数据,读纬度 latude = br.readLine(); if (null == latude) { // 退出循环 break; } // 读下一行数据,读海拔 elevation = br.readLine(); if (null == latude) { // 退出循环 break; } // 加入一个点 pointList.add(gps2point(longtude, latude, elevation)); } in.close(); System.out.println("\n\n"); } catch (Exception e) { in.close(); e.printStackTrace(); } return pointList; }
问题彻底解决
-----
第二次解决:
实际测试后发现这个问题还没有解决,最终又找了些方法,经过一段时间的测试,似乎解决了问题:
具体步骤如下:
linux为redhat服务器版本(非个人版),必须设置的内容:
1、/etc/pam.d/login 添加
session required /lib/security/pam_limits.so
# 注意看这个文件的注释
具体文件的内容为:
[root@**** ~]# vi /etc/pam.d/login #%PAM-1.0 auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so auth include system-auth account required pam_nologin.so account include system-auth password include system-auth # pam_selinux.so close should be the first session rule session required pam_selinux.so close session optional pam_keyinit.so force revoke session required pam_loginuid.so session include system-auth session optional pam_console.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open ~ "/etc/pam.d/login" 15L, 644C
修改后的内容:
-bash: [root@****: command not found [root@**** ~]# clear [root@**** ~]# cat /etc/pam.d/login #%PAM-1.0 auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so auth include system-auth account required pam_nologin.so account include system-auth password include system-auth # pam_selinux.so close should be the first session rule session required pam_selinux.so close session optional pam_keyinit.so force revoke session required pam_loginuid.so session include system-auth session optional pam_console.so # pam_selinux.so open should only be followed by sessions to be executed in the user context session required pam_selinux.so open # kevin.xie added, fixed 'too many open file' bug, limit open max files 1024, 2011-10-24 session required /lib/security/pam_limits.so [root@**** ~]#
2. /etc/security/limits.conf 添加
root – nofile 1006154
root 是一个用户,如果是想所有用户生效的话换成 * ,设置的数值与硬件配置有关,别设置太大了。
修改前内容
[root@**** ~]# cat /etc/security/limits.conf # /etc/security/limits.conf # #Each line describes a limit for a user in the form: # #<domain> <type> <item> <value> # #Where: #<domain> can be: # - an user name # - a group name, with @group syntax # - the wildcard *, for default entry # - the wildcard %, can be also used with %group syntax, # for maxlogin limit # #<type> can have the two values: # - "soft" for enforcing the soft limits # - "hard" for enforcing hard limits # #<item> can be one of the following: # - core - limits the core file size (KB) # - data - max data size (KB) # - fsize - maximum filesize (KB) # - memlock - max locked-in-memory address space (KB) # - nofile - max number of open files # - rss - max resident set size (KB) # - stack - max stack size (KB) # - cpu - max CPU time (MIN) # - nproc - max number of processes # - as - address space limit # - maxlogins - max number of logins for this user # - maxsyslogins - max number of logins on the system # - priority - the priority to run user process with # - locks - max number of file locks the user can hold # - sigpending - max number of pending signals # - msgqueue - max memory used by POSIX message queues (bytes) # - nice - max nice priority allowed to raise to # - rtprio - max realtime priority # #<domain> <type> <item> <value> # #* soft core 0 #* hard rss 10000 #@student hard nproc 20 #@faculty soft nproc 20 #@faculty hard nproc 50 #ftp hard nproc 0 #@student - maxlogins 4 # End of file [root@**** ~]# [root@**** ~]# cat /etc/security/limits.conf # /etc/security/limits.conf # #Each line describes a limit for a user in the form: # #<domain> <type> <item> <value> # #Where: #<domain> can be: # - an user name # - a group name, with @group syntax # - the wildcard *, for default entry # - the wildcard %, can be also used with %group syntax, # for maxlogin limit # #<type> can have the two values: # - "soft" for enforcing the soft limits # - "hard" for enforcing hard limits # #<item> can be one of the following: # - core - limits the core file size (KB) # - data - max data size (KB) # - fsize - maximum filesize (KB) # - memlock - max locked-in-memory address space (KB) # - nofile - max number of open files # - rss - max resident set size (KB) # - stack - max stack size (KB) # - cpu - max CPU time (MIN) # - nproc - max number of processes # - as - address space limit # - maxlogins - max number of logins for this user # - maxsyslogins - max number of logins on the system # - priority - the priority to run user process with # - locks - max number of file locks the user can hold # - sigpending - max number of pending signals # - msgqueue - max memory used by POSIX message queues (bytes) # - nice - max nice priority allowed to raise to # - rtprio - max realtime priority # #<domain> <type> <item> <value> # #* soft core 0 #* hard rss 10000 #@student hard nproc 20 #@faculty soft nproc 20 #@faculty hard nproc 50 #ftp hard nproc 0 #@student - maxlogins 4 # kevin.xie added, fixed 'too many open file' bug, limit open max files 1024, 2011-10-24 * - nofile 102400 # End of file [root@**** ~]#
修改后的内容
3. 修改 /etc/rc.local 添加
echo 8061540 > /proc/sys/fs/file-max
修改前内容
[root@**** ~]# cat /proc/sys/fs/file-max 4096 [root@**** ~]#
修改后内容
[root@**** ~]# cat /proc/sys/fs/file-max 4096000 [root@**** ~]#
做完3个步骤,就可以了。
**************************************
补充说明:
/proc/sys/fs/file-max
该文件指定了可以分配的文件句柄的最大数目。如果用户得到的错误消息声明由于打开文件数已经达到了最大值,从而他们不能打开更多文件,则可能需要增加该值。可将这个值设置成有任意多个文件,并且能通过将一个新数字值写入该文件来更改该值。
缺省设置:4096
/proc/sys/fs/file-nr
该文件与 file-max 相关,它有三个值:
已分配文件句柄的数目
已使用文件句柄的数目
文件句柄的最大数目
该文件是只读的,仅用于显示信息。
关于“打开文件数”限制
Linux系统上对每一个用户可使用的系统资源都是有限制的,这是多用户系统必然要采用的一种资源管理手段,试想假如没有这种机制,那么任何一个普通用户写一个死循环程序,用不了多久系统就要“拒绝服务”了。
今天我遇到了tomcat日志报的错误信息”too many open files”,第一意识就想到了是ulimit控制的”open files“限制。然而问题来了。我在/etc/profile里加入了 ulimit -n 4096保存之后,普通用户登录的时候均会收到一条错误信息ulimit: open files: cannot modify limit: Operation not permitted。然后普通用户的open files限制还是默认值1024。
然后开始在互联网上搜索关于ulimit的信息。互联网果然方便,信息铺天盖地。大家也可以搜一下试一下。其中我了解到两个以前不知道的相关内容。
第一个是内核参数 fs.file-max ,影射为 /proc/sys/fs/file-max
第二个是配置文件 /etc/security/limits.conf
其中大部分的信息中提到 将 /proc/sys/fs/file-max的值设置为4096和ulimit -n 4096是相同的效果。对此我很怀疑,为什么呢?首先ulimit 是一个普通用户也可以使用的命令,而fs.file-max只有root有权设置。其次,很明显fs.file-max是一个全局的设置,而ulimit 是一个局部的设置,很明显的是不相同的。
带着疑虑,又在网上搜索了许久,未果(实际上是我搜索的关键字不够准确)。
最后终于在内核文档/usr/src/linux/Documentation/sysctl/fs.txt里找到下面一段话:
file-max & file-nr:
The kernel allocates file handles dynamically, but as yet it doesn’t free them again. The value in file-max denotes the maximum number of file-handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit.
The three values in file-nr denote the number of allocated file handles, the number of unused file handles and the maximum number of file handles. When the allocated file handles come close to the maximum, but the number of unused file handles is significantly greater than 0, you’ve encountered a peak in your usage of file handles and you don’t need to increase the maximum.
这两段话的大致意思是:
内核动态地分配和释放“file handles”(句柄)。file-max的值是内核所能分配到的最大句柄数。当你收到大量关于句柄用完的错误信息时,你可以需要增加这个值以打破老的限制。
file-nr中的三个值的含意分别是:系统已经分配出去(正在使用)的句柄数,没有用到的句柄数和所有分配到的最大句柄数。当分配出去的句柄数接近 最大句柄数,而“无用的句柄数”大于零时,表明你遇到了一个“句柄”使用高峰,这意为着你不需要增加file-max的值。
看完这段话,相信大家都明白了。file-max是系统全局的可用句柄数。根据我后来又翻查的信息,以及对多个系统的查看求证,这个参数的默认值是跟内存大小有关系的,增加物理内存以后重启机器,这个值会增大。大约1G内存10万个句柄的线性关系。
再回过头来看这两段话,不知道你意识到了没有,文中只提到了file-max的增加,而没有提到了该值的减少。那些在操作ulimit时同时操 作了file-max的哥们儿,估计无一例外地将file-max设置成了4096或者2048。但以似乎也没有因此而导致系统无法打开文件或者建议连 接。(实际上,我将file-max的值设备成256,然后使用shell编写用vi打开500个文件角本运行,并没有得到任何错误信息,查看file- nr的值,系统当前分配的句柄值已经远超过了后面的最大值。所以我猜想对于file-max的任何减少的操作都是毫无意义的,姑且不去管他。实践中需要减 少file-max的时候总是不多见的。 )实事证明我犯了一个致命的错误。我测试的时候使用的是root用户,而当我再次使用普通用户测试的时候,预料中的错误信息出现了:”Too many open files in system”。可见,file-max的减少对系统也是影响力的。前面的结论“所以我猜想对于file-max的任何减少的操作都是毫无意义的”是错误 的。
然后便是/etc/security/limits.conf文件,这个文件很简单,一看就能明白。
于是我按照注释中描述的格式两个两行:
* soft nofile 4096
* hard nofile 4096
恐怖的是,网上居然有人说改了这个设置是需要重启系统的!实在是让人想不通啊,鼎鼎大名的UNIX系统,怎么可能因为这么小小的一个改动就需要 重启系统呢?结果当我再次以普通用户登录的时候,那个”ulimit: open files: cannot modify limit: Operation not permitted”提示没有了,查看ulimit -n,果然已经变成了4096。
linux lsof 修改句柄限制(转)
在Linux下,我们使用ulimit -n 命令可以看到单个进程能够打开的最大文件句柄数量(socket连接也算在里面)。系统默认值1024。
对于一般的应用来说(象Apache、系统进程)1024完全足够使用。但是如何象squid、mysql、java等单进程处理大量请求的应用来说就有点捉襟见肘了。如果单个进程打开的文件句柄数量超过了系统定义的值,就会提到“too many files open”的错误提示。如何知道当前进程打开了多少个文件句柄呢?下面一段小脚本可以帮你查看:
lsof -n |awk ‘{print $2}’|sort|uniq -c |sort -nr|more
在系统访问高峰时间以root用户执行上面的脚本,可能出现的结果如下:
# lsof -n|awk ‘{print $2}’|sort|uniq -c |sort -nr|more
131 24204
57 24244
57 24231
56 24264
其中第一行是打开的文件句柄数量,第二行是进程号。得到进程号后,我们可以通过ps命令得到进程的详细内容。
ps -aef|grep 24204
mysql 24204 24162 99 16:15 ? 00:24:25 /usr/sbin/mysqld
哦,原来是mysql进程打开最多文件句柄数量。但是他目前只打开了131个文件句柄数量,远远底于系统默认值1024。
但是如果系统并发特别大,尤其是squid服务器,很有可能会超过1024。这时候就必须要调整系统参数,以适应应用变化。Linux有硬性限制和软性限制。可以通过ulimit来设定这两个参数。方法如下,以root用户运行以下命令:
ulimit -HSn 4096
以上命令中,H指定了硬性大小,S指定了软性大小,n表示设定单个进程最大的打开文件句柄数量。个人觉得最好不要超过4096,毕竟打开的文件句柄数越多响应时间肯定会越慢。设定句柄数量后,系统重启后,又会恢复默认值。如果想永久保存下来,可以修改.bash_profile文件,可以修改 /etc/profile 把上面命令加到最后。
仍未处理的问题:
为什么redhat9的个人版按照以上的方式修改1024tcp连接限制依然不行呢?
是因为个人版最多支持1024个tcp连接,还是修改方式、相关文件会有所不同?
以上内容,来源网络并加自己亲自测试,经过测试,似乎没有再出现过问题,但不知道是否真的解决,有待更长时间的测试看看
第三次解决--还解决不了,就彻底无语了(经过压力测试,运行7天再也没有出现该问题)
问题的原因是:原来的MINA2程序之关了IoSession,并没有关闭IoConnector实例,但恰恰就是因为没有关闭每次打开的IoConnector实例,造成了"Too many open files ".
原来的程序:
/** * <pre><b>功能描述:</b>获取异步的session实例。 * * @author :Kevin.xie * <b>创建日期 :</b>2011-9-15 上午10:06:27 * * @return * * <b>修改历史:</b>(修改人,修改时间,修改原因/内容) * * </pre> */ public static IoSession getSession1() { // 创建客户端连接器 IoConnector connector = new NioSocketConnector(); // 设置事件处理器 connector.setHandler(new WebClientHandler()); // 设置编码过滤器和按行读取数据模式 connector.getFilterChain() .addLast("codec", new ProtocolCodecFilter(new ObdDemuxingProtocolCodecFactory(false))); // 创建连接 ConnectFuture future = connector.connect(new InetSocketAddress(ServerConfigBoundle.getServerIp(), ServerConfigBoundle.getServerPort())); // 等待连接创建完成 future.awaitUninterruptibly(); // 获取连接会话 IoSession session = future.getSession(); return session; } /** * <pre><b>功能描述:</b>必须要关闭Connector和IoSession * @author :Kevin.xie * <b>创建日期 :</b>2011-10-20 上午10:20:54 * * @param session 要关闭的session * * <b>修改历史:</b>(修改人,修改时间,修改原因/内容) * * </pre> */ public static void closeSession(IoSession session) { if (session != null && !session.isClosing()) { // 没有关闭,就关闭 session.close(true); session = null; } }
修改后的程序
/** * * <pre><b>功能描述:</b>获取IoConnector和异步的session实例 * 无法关闭。特别的提醒,NioSocketConnector 也要关闭。 * 函数名是 dispose()。这点特别重要。这次出现 too many open files 的问题根源在这里 * * @author :Kevin.xie * <b>创建日期 :</b>2011-9-15 上午10:06:27 * * @return * * <b>修改历史:</b>(修改人,修改时间,修改原因/内容) * * </pre> */ public static Map<String, Object> getConnectorAndSession() { // 创建客户端连接器 IoConnector connector = new NioSocketConnector(); // 设置事件处理器 connector.setHandler(new WebClientHandler()); // 设置编码过滤器和按行读取数据模式 connector.getFilterChain() .addLast("codec", new ProtocolCodecFilter(new ObdDemuxingProtocolCodecFactory(false))); // 创建连接 ConnectFuture future = connector.connect(new InetSocketAddress(ServerConfigBoundle.getServerIp(), ServerConfigBoundle.getServerPort())); // 等待连接创建完成 future.awaitUninterruptibly(); // 获取连接会话 IoSession session = future.getSession(); Map<String, Object> map = new HashMap<String, Object>(); map.put(CONNECTOR_KEY, connector); map.put(SESSION_KEY, session); return map; } /** * * <pre><b>功能描述:</b>必须要关闭Connector和IoSession * 特别的提醒,NioSocketConnector 也要关闭。 * 函数名是 dispose()。这点特别重要。这次出现 too many open files 的问题根源在这里 * @author :Kevin.xie * <b>创建日期 :</b>2011-10-20 上午10:20:54 * * @param connector 要关闭的IoConnector,不关闭会报 too many open files 错误 * @param session 要关闭的session * * <b>修改历史:</b>(修改人,修改时间,修改原因/内容) * * </pre> */ public static void closeConnectorAndSession(IoConnector connector, IoSession session) { if (session != null && !session.isClosing()) { // 没有关闭,就关闭 session.close(true); session = null; } if (connector != null && !(connector.isDisposing() || connector.isDisposed())) { // 没有关闭,就关闭 connector.dispose(); connector = null; } } ]
用完后一定要释放资源:
Map<String, Object> resultMap = SocketUtils.getConnectorAndSession(); IoSession session = (IoSession) resultMap.get(SocketUtils.SESSION_KEY); IoConnector connector = (IoConnector) resultMap.get(SocketUtils.CONNECTOR_KEY); ............ ............ // 主动关闭连接 SocketUtils.closeConnectorAndSession(connector, session);
同时在配置文件 /etc/security/limits.conf 加了一个配置(该不该问题不大):
# kevin.xie added, fixed 'too many open file' bug', 2012-01-04
* soft nofile 65536
* hard nofile 65536
# 第二次解决添加的内容 # kevin.xie added, fixed 'too many open file' bug, limit open max files 1024, 2011-10-24 * - nofile 102400 # 第三次(本次)解决添加的问题(不过这个应该可以不修改,没有印证,也懒得修改了) # kevin.xie added, fixed 'too many open file' bug', 2012-01-04 * soft nofile 65536 * hard nofile 65536
评论
6 楼
Veer-273
2015-06-08
很不错的额!
5 楼
石頭剪刀b
2015-02-06
我们项目也出现了这种情况。具体还有待分析出现的原因,还是谢谢%楼主。
4 楼
xieyanhua
2012-03-07
weihuijing123 写道
谢谢!很有用。
能帮助到你,感到很开心
3 楼
weihuijing123
2012-03-07
谢谢!很有用。
2 楼
xieyanhua
2012-01-12
能不能把你的bugs发来看看,因为这个问题,我也是经过三次修改后,才彻底解决该问题。我是遇到了错误信息:“Too many open files”和“No buffer space availabel”,从我的项目上看,两个问题都是因为使用MINA2时,有些资源没有关闭造成的。但是出现“Too many open files”的错误(linux上面,windows下没有发现该问题) ,肯定是因为linux下对每个进程打开系统资源数的限制,默认是1024,打开了资源没有释放。所以如果是“Too many open files”错误,肯定是你的程序里打开了资源没有释放!
刚开始遇到这个错误,我也以为是linux自己配置的的问题,节后解决过程如下:
第一次解决,因为对linux不是很熟悉,以为是linux服务器配置的问题(默认安装的配置) :
按上面的步骤(第一和第二步修改,方法一和方法2都修改了),情况好转,以为解决了。但时间一长问题又重现了。因为开始系统打开的资源少,所以问题重现的时间间隔就比较长。人因都是人为发送请求。所以有时时候一两个星期都不出现,如果操作平率高的话,就出现快点了。
第二次解决,因为发现第一次方法没有解决好问题。依然以为是linux配置的问题,在第一次的基础上,所以又看了资料,于是有了第二次解决,方法就是按上面的第三步的操作,修改了一些配置文件。该完后,发现情况好了很多,两三个星期都不见有问题。但后来程序上使用的定时调度任务,每隔几分钟会就会打开十几个请求链接,这样一跑,快的话,不到半个小时就出现问题了。
第三次解决,这次基本上不认为是服务器本省的问题,肯定是程序那里出问题,所以又看了很多资料,最后终于解决了问题(经过测试,目前其了5个任务,每个人物6个线程,所有任务基本在20~5分钟内完成,比第二修改后的任务多了5倍这样,请求时间间隔也短了很多),经过7天的运行,没有再出现过一次这样的错误。
问题的原因是:原来的MINA2程序之关了IoSession,并没有关闭IoConnector实例,但恰恰就是因为没有关闭每次打开的IoConnector实例,造成了"Too many open files ".
具体看原帖,我已在后面更新了
刚开始遇到这个错误,我也以为是linux自己配置的的问题,节后解决过程如下:
第一次解决,因为对linux不是很熟悉,以为是linux服务器配置的问题(默认安装的配置) :
按上面的步骤(第一和第二步修改,方法一和方法2都修改了),情况好转,以为解决了。但时间一长问题又重现了。因为开始系统打开的资源少,所以问题重现的时间间隔就比较长。人因都是人为发送请求。所以有时时候一两个星期都不出现,如果操作平率高的话,就出现快点了。
第二次解决,因为发现第一次方法没有解决好问题。依然以为是linux配置的问题,在第一次的基础上,所以又看了资料,于是有了第二次解决,方法就是按上面的第三步的操作,修改了一些配置文件。该完后,发现情况好了很多,两三个星期都不见有问题。但后来程序上使用的定时调度任务,每隔几分钟会就会打开十几个请求链接,这样一跑,快的话,不到半个小时就出现问题了。
第三次解决,这次基本上不认为是服务器本省的问题,肯定是程序那里出问题,所以又看了很多资料,最后终于解决了问题(经过测试,目前其了5个任务,每个人物6个线程,所有任务基本在20~5分钟内完成,比第二修改后的任务多了5倍这样,请求时间间隔也短了很多),经过7天的运行,没有再出现过一次这样的错误。
问题的原因是:原来的MINA2程序之关了IoSession,并没有关闭IoConnector实例,但恰恰就是因为没有关闭每次打开的IoConnector实例,造成了"Too many open files ".
具体看原帖,我已在后面更新了
1 楼
zhangyou1010
2012-01-12
我们项目也出现了这个问题。
相关推荐
mina-core-2.0.0-M6.jar mina-example-2.0.0-M6.jar mina-filter-codec-netty-2.0.0-M6.jar mina-filter-compression-2.0.0-M6.jar mina-integration-beans-2.0.0-M6.jar mina-integration-jmx-2.0.0-M6.jar mina-...
hive 开发UDF 使用maven工程 引发jar包缺失 hive 开发UDF 使用maven工程 引发jar包缺失
mina-filter-compression-2.0.7.jar,mina 过滤器jar包,核心包之一
在这个场景中,我们关注的是MINA的核心组件以及两个特定的过滤器和传输组件:`mina-core-2.0.0-RC1.jar`、`mina-filter-compression-2.0.0-RC1.jar`和`mina-transport-apr-2.0.0-RC1.jar`。 **MINA Core (mina-core...
mina-integration-ognl-2.0.0-M4.jar mina-integration-ognl-2.0.0-M4.jar
mina-core-2.0.0-M1-sources.jar是构建mina框架的主要文件
Apache MINA是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利...当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发、串口通讯程序(只在最新的预览版中提供)。
"mina-pull-down-refresh-master.zip"这个压缩包提供的解决方案,旨在完美解决这一难题。 1. 微信小程序ScrollView概述: 微信小程序中的ScrollView组件是用于展示可滚动内容的容器,可以垂直或水平滚动。它支持...
标题"apache-mina-2.0.16"表明我们讨论的是MINA项目的2.0.16版本,这是一个稳定且功能丰富的发行版。 描述中的"apache-mina-2.0.16.zip"是指这个版本的源代码或二进制库被打包成ZIP文件供用户下载。ZIP文件是常见的...
mina-integration-beans-2.0.0-M4.jar mina-integration-beans-2.0.0-M4.jar
这个"apache-mina-3.0.0-M2-src.zip"文件包含了MINA 3.0.0 Milestone 2版本的源代码和相关文档。 MINA的核心特性包括: 1. **异步I/O模型**:MINA使用Java NIO(New I/O)库,支持非阻塞I/O操作,这提高了处理大量...
mina-core-2.0.0-M1.jar/mina-example-1.0.5.jar/slf4j-jdk14-1.6.1.jar/slf4j-log4j12-1.6.1.jar mina 所用jar
《mina-core-2.0.0-M1.jar与SLF4J:构建高效网络通信与日志记录》 mina-core-2.0.0-M1.jar是Apache Mina项目的核心库,它是一个高度可扩展的网络通信框架,主要用于构建高性能、高效率的服务端和客户端应用程序。...
mina-core-1.1.7-sources.jar mina-filter-compression-1.1.7-sources.jar mina-filter-ssl-1.1.7-sources.jar mina-filter-ssl.jar slf4j-api-1.5.8-sources.jar slf4j-log4j12-1.5.8-sources.jar Openfire3.10...
《mina-http-2.0.7.jar:Java中的MINA框架与HTTP支持详解》 MINA(Multipurpose Infrastructure for Network Applications)是一个强大的网络应用程序框架,它由Apache软件基金会开发,主要用于构建高性能、高效率...
2. **mina-core-2.0.0-RC1-sources.jar**:这个文件包含了mina-core的源代码,对于开发者来说,它是理解和定制MINA行为的关键资源。通过阅读源码,开发者可以更深入地了解MINA的工作原理,调试问题,甚至为MINA贡献...
这个压缩包"apache-mina-0.0.19-bin.tar.gz"包含了Apache MINA 0.0.19版本的二进制文件。 Apache MINA的核心特性包括: 1. **异步I/O**:MINA 使用Java NIO(Non-blocking I/O)库,允许开发者编写高性能、高并发...
基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发...
mina-core-2.0.0-RC1-sources.jar
标题中的"Apache-Mina-2.rar"和"mina-mina-core-1.1.3"表明这是关于Apache Mina 2.x版本,特别是其核心模块的1.1.3版本。 Apache Mina的名称来源于"Multi-purpose Infrastructure for Network Applications",它...