解決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的流是否在操作完之后關閉,這才是從最更本上的解決。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM