轉載註明出處,謝謝~
前段時間幫助公司解決了一次tomcat環境服務器的異常,今天有時間過來總結一下。
問題的表現:
tomcat服務在重啓之後,短時間內會承受大量訪問,由於這個時候緩存還沒建立,每次訪問都將消耗一定資源(數據庫連接或者文件IO),併發量在2000左右的時候tomcat服務開始拋出大量Too Many Open Files的異常,主要是文件IO一塊的異常,數據庫連接池配置恰當就不會拋異常。
問題分析:
這是一個典型的文件句柄耗盡的異常,在linux裏頭“一切皆文件”,所以雖然提示“文件”打開太多,其實也有可能是socket打開太多或者設備打開太多。
文件句柄是用來幹嘛的?
簡單看來程序通過句柄獲得資源的引用,來進行資源的打開和關閉的操作。
爲什麼會出現文件句柄耗盡的情況?
主要是因爲linux在文件句柄的數目上有兩個級別的限制。一個是系統級別的總數限制,一個是針對用戶的限制。默認情況下每個用戶所能使用的句柄數是1024。一般情況下1024也夠用了,但是在大容量的系統上,特別是會頻繁使用網絡通信和文件IO的系統上,1024很快就被耗光了。所以首先我們要調整這個值。修改方法如下:
具體這個值應該設置成多少?
優先級(Open File Descriptors):
soft limit < hard limit < kernel < 實現最大file descriptor數採用的數據結構所導致的限制
其實這個值倒是沒有具體限制,但是分配的值如果太大反而會影響系統性能,所以要根據具體應用調配權衡。
問題的解決方案:
首先當然是修改linux句柄數限制到一個合適的值。
然後就是應用本身的一個調整。有這麼幾種情況:
1.數據庫連接池的優化。必須要使用連接池,否則句柄沒耗光數據庫就崩了。。。
2.抓取資源的時候有可能會用到HttpClient,儘量也應該使用連接池來控制連接數。
關於HttpClient的連接池配置可以查看我另外一文:http://blog.csdn.net/shootyou/archive/2011/05/12/6415248.aspx
3.連接池設置的把握,建立連接超時時間,讀取超時時間,連接數目,等待時間,等都需要配置到一個合適的值,否則發揮不出連接池的性能。
2015-05-12更新:
具體可以參考:http://www.dbi-services.com/index.php/blog/entry/linux-how-to-monitor-the-nproc-limit-1