解决Linux中出现Too many open files

Too many open files  问题出现有两种情况:
一种是在搜索的时候出现,多半是由于索引创建完毕之后被移动过,如果创建索引的时候不出现该错误,搜索的时候也一般是不会出现的。如果出现了,有两种处理办法,一种是修改合并因子和最小合并因子,并且使用
IndexWriter.Optimize() 
优化索引,这样会将索引文件数量减少到文件系统限制之内;另外一种办法是修改操作系统的打开文件数量限制。方法如下:
1. 
按照最大打开文件数量的需求设置系统,  并且通过检查 /proc/sys/fs/file-max 文件来确认最大打开文件数已经被正确设置。  
# cat /proc/sys/fs/file-max
如果设置值太小,  修改文件 /etc/sysctl.conf 的变量到合适的值。  这样会在每次重启之后生效。  如果设置值够大,跳过下步。  
# echo 2048 > /proc/sys/fs/file-max
编辑文件 /etc/sysctl.conf ,插入下行。  
fs.file-max = 8192  然后,执行命名: sysctl -p
2. 
/etc/security/limits.conf 文件中设置最大打开文件数,  下面是一行提示:  

添加如下这行。  
* - nofile 8192
这行设置了每个用户的默认打开文件数为 2048   注意 "nofile" 项有两个可能的限制措施。就是项下的 hard soft   要使修改过得最大打开文件数生效,必须对这两种限制进行设定。  如果使用 "-" 字符设定 hard soft 设定会同时被设定。  
硬限制表明 soft 限制中所能设定的最大值。  soft 限制指的是当前系统生效的设置值。  hard 限制值可以被普通用户降低。但是不能增加。  soft 限制不能设置的比 hard 限制更高。  只有 root 用户才能够增加 hard 限制值。  
当增加文件限制描述,可以简单的把当前值双倍。  例子如下,  如果你要提高默认值 1024   最好提高到 2048   如果还要继续增加,  就需要设置成 4096  
另外一种情况是在创建索引的时候,也有两种可能,一种是  合并因子太小,导致创建文件数量超过操作系统限制,这时可以修改合并因子,也可以修改操作系统的打开文件数限制;另外一种是合并因子受虚拟机内存的限制,无法调整到更大,而  需要索引的 doc  数量又非常的大,这个时候就只能通过修改操作系统的打开文件数限制来解决了。  
在此基础上,我还修改了以下一个配置文件
vi /etc/sysctl.conf 
添加:
# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 30
# Decrease the time default value for tcp_keepalive_time connection
net.ipv4.tcp_keepalive_time = 1800
# Turn off tcp_window_scaling
net.ipv4.tcp_window_scaling = 0
# Turn off the tcp_sack
net.ipv4.tcp_sack = 0
#Turn off tcp_timestamps
net.ipv4.tcp_timestamps = 0
然后  service network restart, 这些都和 TCP sockets 有关的优化。
另外需要在  /etc/rc.d/rc.local 里添加已使得重启的时候生效。
echo "30">/proc/sys/net/ipv4/tcp_fin_timeout
echo "1800">/proc/sys/net/ipv4/tcp_keepalive_time
echo "0">/proc/sys/net/ipv4/tcp_window_scaling
echo "0">/proc/sys/net/ipv4/tcp_sack
echo "0">/proc/sys/net/ipv4/tcp_timestamps
因为不是所有的程序都在 root 下跑的,所有 linux 有对 hard  soft open files  的区分,普通用户受 hard 的限制,无论 ulimit -n $ 数值调到多高,都跑不到  /etc/security/limits.conf nofile 的值 .
这样的优化后  lsof -p $java_pid|wc -l 可以跑到 4 千以上都不会抛出 too many open files
但是我们通过以上的文章详细介绍知道,这样也是治标不治本,找到 java 哪个文件不关闭文件描述符或者被请求过多的原因才是最重要的!

 

 

最近随着网站访问量的提高把web服务器移到linux下了,在移服务器的第二天,tomcat频繁的报

 

java.net.SocketException: Too many open files错误,错误日志达到了100多兆,郁闷了,windows上运行了很长

 

时间都没出现这个错误,后来才知道linux对进程的打开文件数是有限制的。

 

用命令ulimit -a查看

[root@test security]# ulimit -a
core file size        (blocks, -c) 0
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
max locked memory     (kbytes, -l) unlimited
max memory size       (kbytes, -m) unlimited
open files                    (-n) 1024
pipe size          (512 bytes, -p) 8
stack size            (kbytes, -s) 8192
cpu time             (seconds, -t) unlimited
max user processes            (-u) 7168
virtual memory        (kbytes, -v) unlimited
[root@test security]#
通过以上命令,我们可以看到open files 的最大数为1024

 

对于并发量比较大的网站这个限制是有些捉襟见肘的,所以我通过这个命令

 

ulimit -n 4096
把打开文件数的上限设为了4096,这下好了,项目又稳定了

 

没想到过两天后又重新出这个错误了,郁闷,两个小时报一次,报之后就挂掉了

 

在重新用ulimit -a查看,发现open files    (-n) 1024 又变回了1024了,

 

报这个错误就在我那次登陆更新之后又报的,原来ulimit -n 4096 命令只能临时的改变open files  的值,当

 

 

重新登陆后又会恢复,所以需要永久设置open files  的值才行啊,

 

用ulimit -n 修改open files 总是不能保持。所以用下面一个简单的办法更好些。

修改/etc/security/limits.conf 添加如下一行:

* - nofile 1006154

修改/etc/pam.d/login添加如下一行

session required /lib/security/pam_limits.so

 

这次永久修改后程序就再没那个问题了,一直稳定运行。

 

另外遇到这个问题这后还需要检查我们的程序对于操作io的流是否在操作完之后关闭,这才是从最更本上的解决。

 

 

你可能感兴趣的:(linux)