文章出處

一、問題現象

運維實戰案例之“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文件的修改時間,操作如下圖所示:

wKiom1OxIoXAY-q6AADyDaNe9Vs461.jpg

通過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

文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()