問題描述
tomcat日誌中報too many open files導致程序無法讀取文件錯誤。
報錯原因
出現這句提示的原因是程序打開的文件/socket連接數量超過系統設定值。
java.IOException:打開的文件過多
經搜索,發現是由於Linux默認設置的句柄數為1024,當併發量過大,就不夠用了;
原因:
操作系統的中打開文件的最大句柄數受限所致,常常發生在很多個併發用戶訪問服務器的時候.因為為了執行每個用戶的應用服務器都要加載很多文件(new一個socket就需要一個文件句柄),這就會導致打開文件的句柄的缺乏.
解決:
- 儘量把類打成jar包,因為一個jar包只消耗一個文件句柄,如果不打包,一個類就消耗一個文件句柄.
- java的垃圾回收不能關閉網絡連接打開的文件句柄,如果沒有執行close()(例如:java.net.Socket.close())則文件句柄將一直存在,而不能被關閉.你也可以考慮設置socket的最大打開數來控制這個問題.
- 對操作系統做相關的設置,增加最大文件句柄數量。
增加最大文件句柄數量:
nofile(可打開的文件描述符的最大數)和nproc(單個用戶可用的最大進程數量)
cp /etc/security/limits.conf /etc/security/limits.conf_bak
echo "### add by css ### " >>/etc/security/limits.conf
echo "* soft nofile 65536" >>/etc/security/limits.conf
echo "* hard nofile 65536" >>/etc/security/limits.conf
echo "* soft nproc 65536" >>/etc/security/limits.conf
echo "* hard nproc 65536" >>/etc/security/limits.conf
重啟系統,才能生效.
ulimit -a 查看所有設置
ulimit -u 65535(新的open files 值)修改設置
ulimit -n 65536 設置用戶可以同時打開的最大文件數(max open files) 默認是2048
如果本參數設置過小,對於併發訪問量大的網站,可能會出現too many open files的錯誤 。
使用lsof -p pid [httpd進程的 pid、java的pid]來查看系統中apache進程和java運行時進程當前打開的文件資源:
lsof -p `ps -ef|grep tomcat|grep -v "grep --color=auto tomcat"|awk '{print $2}'` | wc -l
閱讀更多 信息安全攻與防 的文章