天天看點

Tomcat Too Many Open Files

Tomcat Too Many Open Files ;Too many open files tomcat 6.0報“too many open files Too many open files 問題的解決 linux 故障解決,tomcat 故障處理,too many open files 故障處理
發表于 2011 年 01 月 06 日 由 admin 
Tomcat Too Many Open Files ;Too many open files tomcat 6.0報“too many open files Too many open files 問題的解決

linux 故障解決,tomcat 故障處理,too many open files 故障處理這個問題是第一次在Linux環境下碰到,把解決的方法記錄下來。

伺服器配置:兩個雙核CPU 2.0G,4G記憶體
作業系統:CentOS,核心2.6.18


應用1、搜尋伺服器,負責全站的搜尋和提供内容相關性接口
應用伺服器:Tomcat6.0.16+Apache2.2.8,其中兩個Tomcat執行個體,一個對外提供服務,一個對内管理索引(建立、删除、檢索等)
Web方案:Solr1.3(With Solr Client For Java)、Java Servlet(Web Service 接口)

應用2、類似于百度知道的一個應用
應用伺服器:與搜尋伺服器共享Apache2.2.8
Web方案:Php+Mysql

問題症狀:搜尋服務停止,應用2響應逾時,牽連全站的搜尋接口調用内容的輸出,檢視Catalina日志,大量的如下資訊:
<!--[if !supportLineBreakNewLine]-->

Java代碼
org.apache.jk.common.ChannelSocket acceptConnections
WARNING: Exception executing accept
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at org.apache.jk.common.ChannelSocket.accept(ChannelSocket.java:295)
at org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:641)
at org.apache.jk.common.SocketAcceptor.runIt(ChannelSocket.java:852)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source) 

org.apache.jk.common.ChannelSocket acceptConnections
WARNING: Exception executing accept
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(Unknown Source)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at org.apache.jk.common.ChannelSocket.accept(ChannelSocket.java:295)
at org.apache.jk.common.ChannelSocket.acceptConnections(ChannelSocket.java:641)
at org.apache.jk.common.SocketAcceptor.runIt(ChannelSocket.java:852)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Unknown Source)
<!--[endif]-->事件的主題:linux系統出現Too many open files 錯誤,這是因為檔案描述符大小不夠,或者有不正常的網絡連接配接(Socket也是一種特殊的檔案)、檔案IO沒有關閉并釋放出檔案描述符(檔案句柄,File Operator)。

使用如下指令檢視系統對允許打開最大檔案描述符的配置:
ulimit -u 檢視open files設定
ulimit -a 檢視所有設定
ulimit -u 65535(新的open files 值)修改設定
ulimit -n 65536 設定使用者可以同時打開的最大檔案數(max open files)
 
如果本參數設定過小,對于并發通路量大的網站,可能會出現too many open files的錯誤  
使用lsof -p pid [httpd程序的 pid、java的pid]來檢視系統中apache程序和java運作時程序目前打開的檔案資源,發現兩者之和已經接近1024,大于了預設的設定。

修改配置:

修改/etc/security/limits.conf,在檔案末加上
* soft nofile 65536
* hard nofile 65536

系統級檔案描述符極限還可以通過将以下三行添加到 /etc/rc.d/rc.local 啟動腳本中來設定:
# Increase system-wide file descriptor limit.
echo 65536 > /proc/sys/fs/file-max
echo 65536 > /proc/sys/fs/inode-max 

思考:雖 然調整該參數解決了目前的問題,但并不是最好的方法,出現該錯誤說明該伺服器承載了一定的并發連接配接,尤其是搜尋服務,其中一個執行個體對外提供搜尋,另一個實 例建立索引,兩個執行個體之間也使用socket進行通信(httpclient for java),建立索引的時候會占用大量的檔案描述符,如果描述符沒有及時釋放(不能完全依賴垃圾回收機制,要及時的close);全站的所有與搜尋有關的 接口調用都會向其送出請求,而應用2也對外服務不少的請求,較好的辦法是将搜尋服務從該伺服器中分離出來,這樣可以分别對兩者進行優化(包括調整 Linux系統參數,比如:/etc/sysctl.conf中對net.ipv4的優化),出了問題也容易debug