一、問題現象
運維實戰案例之“Too many open files”錯誤與解決方法,這是一個基于Java的Web應用系統,在后臺添加數據時提示無法添加,于是登錄服務器查看tomcat日志,發現了如下異常信息:
java.io.IOException: Too many open files
通過這個錯誤,基本判斷是系統可用的文件描述符不夠了,由于tomcat服務是系統www用戶啟動的,于是用www用戶登錄系統,通過“ulimit -n”命令查看系統可以打開最大文件描述符的數量,輸出如下:
[www@tomcatserver ~]$ ulimit -n
65535
可以看到這個服務器設置的最大可打開的文件描述符已經是65535了,這么大的一個值應該夠用了,但是為什么還是提示這么個錯誤呢?
二、解決思路
這個案例涉及到linux下ulimit命令的使用,這里簡單介紹下ulimit的作用和使用技巧。ulimit主要是用來限制進程對資源的使用情況的,它支持各種類型的限制,常用的有:
內核文件的大小限制
進程數據塊的大小限制
Shell進程創建文件大小限制
可加鎖內存大小限制
常駐內存集的大小限制
打開文件句柄數限制
分配堆棧的最大大小限制
CPU占用時間限制用戶最大可用的進程數限制
Shell進程所能使用的最大虛擬內存限制
ulimit使用的基本格式為:
ulimit [options] [limit]
具體的options參數含義如下表所示:
選項 含義
-a 顯示當前系統所有的limit資源信息。
-H 設置硬資源限制,一旦設置不能增加。
-S 設置軟資源限制,設置后可以增加,但是不能超過硬資源設置。
-c 最大的core文件的大小,以 blocks 為單位。
-f 進程可以創建文件的最大值,以blocks 為單位.
-d 進程最大的數據段的大小,以Kbytes 為單位。
-m 最大內存大小,以Kbytes為單位。
-n 可以打開的最大文件描述符的數量。
-s 線程棧大小,以Kbytes為單位。
-p 管道緩沖區的大小,以Kbytes 為單位。
-u 用戶最大可用的進程數。
-v 進程最大可用的虛擬內存,以Kbytes 為單位。
-t 最大CPU占用時間,以秒為單位。
-l 最大可加鎖內存大小,以Kbytes 為單位。
在使用ulimit時,有以下幾種使用方法:
(1)在用戶環境變量中加入
如果用戶使用的是bash,那么就可以在用戶目錄的環境變量文件.bashrc或者.bash_profile中加入“ulimit -u 128”來限制用戶最多可以使用128個進程。
(2)在應用程序的啟動腳本中加入
如果應用程序是tomcat,那么就可以在tomcat的啟動腳本startup.sh腳本中加入“ulimit -n 65535”來限制用戶最多可以使用65535個文件描述符。
(3)直接在shell命令終端執行ulimit命令
這種方法的資源限制僅僅在執行命令的終端生效,退出或者關閉終端后,設置失效,并且這個設置不影響其它shell終端。
有時候為了方便起見,也可以將用戶資源的限制統一由一個文件來配置,這個文件就是/etc/security/limits.conf,該文件不但能對指定用戶的資源進行限制,還能對指定組的資源進行限制。該文件的使用規則如下:
其中:
domain表示用戶或者組的名字,還可以使用 * 作為通配符,表示任何用戶或用戶組。
Type 表示限制的類型,可以有兩個值,soft 和 hard,分別表示軟、硬資源限制。
item 表示需要限定的資源名稱,常用的有nofile、cpu、stack等。分別表示最大打開句柄數、占用的cpu時間、最大的堆棧大小。
value 表示限制各種資源的具體數值。
除了limits.conf文件之外,還有一個/etc/security/limits.d目錄,可以將資源限制創建一個文件放到這個目錄中,默認系統會首先去讀取這個目錄下的所有文件,然后才去讀取limits.conf文件。所有資源限制設置完成后,退出shell終端,再次登錄shell終端后,ulimit設置即可自動生效。
三、解決問題
在介紹了ulimit知識后,緊接著上面的案例,既然ulimit設置沒問題,那么一定是設置沒有生效導致的,接下來檢查下啟動tomcat的www用戶環境變量下是否添加了ulimit限制,檢查發現,www用戶下并無ulimit資源限制,于是繼續檢查tomcat啟動腳本startup.sh文件中,是否添加了ulimit限制,檢查發現也并無添加,最后考慮是否將限制加到了limits.conf文件中,于是檢查limits.conf文件,操作如下:
1 2 3[root@tomcatserver ~]# cat /etc/security/limits.conf|grep www www soft nofile 65535 www hard nofile 65535
從輸出可知,ulimit限制是加在了limits.conf文件中,既然限制已經加了,配置也沒有錯,為何還是報錯呢,經過長時間思考,判斷只有一種可能,那就是tomcat的啟動時間早于ulimit資源限制的添加時間,于是首先查看下tomcat的啟動時間,操作如下:
1 2 3 4 5 6 7 8 9[root@tomcatserver ~]# more /etc/issue CentOS release 6.3 (Final) Kernel \r on an \m [root@tomcatserver ~]# uptime 15:10:19 up 283 days, 5:37, 4 users, load average: 1.20, 1.41, 1.35 [root@tomcatserver ~]# pgrep –f tomcat 4667 [root@tomcatserver ~]# ps -eo pid,lstart,etime|grep 4667 4667 Sat Jul 6 09:33:39 2013 77-05:26:02
從輸出看,這臺服務器已經有283天沒有重啟過了,而tomcat是在2013年7月6號9點多啟動的,啟動了近77天零五個半小時了,接著繼續看看limits.conf文件的修改時間,操作如下圖所示:
通過stat命令可以很清楚的看出,limits.conf文件最后的修改時間是2013-07-12,通過查問相關的Linux系統管理人員,他們基本確認就是在這個時候添加的ulimit資源限制,這樣此案例的問題就很明確了。由于ulimit限制的添加時間晚于tomcat最后一次的啟動時間,而在此期間內,tomcat服務一直未重啟過,操作系統也一直未重啟過,那么ulimit資源限制對于tomcat來說始終是不生效的,同時,由于此操作系統是Centos6.3,系統默認的最大可用句柄數是1024,那么java進程還是用的Linux默認的這個值,出現“Too many open files”的錯誤,也是合乎情理的。
問題清楚之后,解決問題的方法非常簡單,重啟tomcat服務即可。
看文倉www.kanwencang.com網友整理上傳,為您提供最全的知識大全,期待您的分享,轉載請注明出處。
歡迎轉載:http://www.kanwencang.com/bangong/20170216/102240.html
文章列表