Jul 21, 2015 8:45:23 AM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run SEVERE: Socket accept failed java.net.SocketException: Too many open files at java.net.PlainSocketImpl.socketAccept(Native Method) at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398) at java.net.ServerSocket.implAccept(ServerSocket.java:530) at java.net.ServerSocket.accept(ServerSocket.java:498) at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60) at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:216) at java.lang.Thread.run(Thread.java:745)解決的思路:
ulimit -a查看Linux內核允許的最大資源
open files (-n) 1024需要調大限制
ulimit -n 65535經過觀察,問題依舊...
lsof|grep tomcat|wc -l看到tomcat的io居然有1082個,立馬想到了nginx與tomcat的不協調造成的,據網絡資料顯示:tomcat端默認開啟了 keepalive,而nginx把連接交給了tomcat並不關系是否關閉,因此tomcat需要等待"connectionTimeout"設置的超 時時間來關閉,所以最好設置“maxKeepAliveRequests”為1,讓每個連接只相應一次就關閉,這樣就不會等待timeout了。因此設置 tomcat:
<Connector port="8080" protocol="HTTP/1.1" maxKeepAliveRequests="1" connectionTimeout="20000" URIEncoding="UTF-8" redirectPort="8443" /> <!-- A "Connector" using the shared thread pool--> <!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" maxKeepAliveRequests="1" connectionTimeout="20000" redirectPort="8443" />重啟tomcat,觀察,問題依舊!
lsof|grep tomcat|more
Jul 21, 2015 3:06:40 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads SEVERE: The web application [/MobileService] appears to have started a thread named [Xmemcached-Reactor-0] but has failed to stop it. This is very likely to create a memory leak.原來在每次重新部署webapp時,tomcat殺不掉XmemcachedClient的連接進程,由於使用的是spring,所以需要在memcachedClient的bean裡增加"destroy-method"。
<listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>經過一天的推理、懷疑、實驗、否定,終於搞定,又過了一次"福爾摩斯"的偵探瘾,作此標記,留給後來人!
<Executor name="mobileThreadPool" namePrefix="catalina-exec-" maxThreads="600" minSpareThreads="20" maxIdleTime="60000" /> <Connector executor="mobileThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" keepAliveTimeout="15000" maxKeepAliveRequests="1" URIEncoding="UTF-8" redirectPort="8443" />
ulimit -n 65535會報異常:
ulimit: max user processes: cannot modify limit原來是被 /etc/security/limits.conf 限制了,打開此文件即可看到,對默認用戶是有限制的,因此可以加入
* soft noproc 65535 * hard noproc 65535 * soft nofile 65535 * hard nofile 65535
這樣就非root用戶就可以設置ulimit為65535了。
設置了ulimit後,我在root下啟動tomcat,壓力還會容易出現“Too many open files”,但其實使用“lsof -u root|wc -l”並不多,才3000+;root後來我單獨建立了個用戶來啟動,暫時沒出現問題。
PS:
/proc/sys/fs/file-max表示kernel中維護的最大文件描述符數目。不管這個系統上有多少了用戶登錄,有多少個進程在運行,所有打開的文件數目總合都不能超過這個數字。
/etc/security/limit.conf用來設置每個用戶最多可以打開的文件數目。
普通用戶可以通過ulimit -n 命令來設置hard limit(只能改小) 和soft limit(可以改大和改小).
把上面的內容概括成3條就是: