java.net.SocketException:Spring Hibernate Tomcat 打开的文件太多
Posted
技术标签:
【中文标题】java.net.SocketException:Spring Hibernate Tomcat 打开的文件太多【英文标题】:java.net.SocketException: Too many open files Spring Hibernate Tomcat 【发布时间】:2014-06-08 19:09:35 【问题描述】:我在生产中的 Linode 服务器上有一个 Hibernate、Spring、Debian、Tomcat、mysql 堆栈,并带有一些客户端。它是一个 Spring-Multitenant 应用程序,可为大约 30 个客户端托管网页。
应用程序启动正常,但过了一会儿,我收到此错误:
java.net.SocketException: Too many open files
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
at java.net.ServerSocket.implAccept(ServerSocket.java:453)
at java.net.ServerSocket.accept(ServerSocket.java:421)
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:662)
然而,在引发此错误之前,nagios 会提醒我对服务器的 ping 操作停止响应。
以前,我将 nginx 作为代理,但每次请求都会收到此 nginx 错误,并且无论如何都必须重新启动 tomcat:
2014/04/21 12:31:28 [error] 2259#0: *2441630 no live upstreams while connecting to upstream, client: 66.249.64.115, server: abril, request: "GET /catalog.do?op=requestPage&selectedPage=-195&category=2&offSet=-197&page=-193&searchBox= HTTP/1.1", upstream: "http://appcluster/catalog.do?op=requestPage&selectedPage=-195&category=2&offSet=-197&page=-193&searchBox=", host: "www.anabocafe.com"
2014/04/21 12:31:40 [error] 2259#0: *2441641 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 200.74.195.61, server: abril, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "www.oli-med.com"
这是我的 server.xml 连接器配置:
<Connector port="80" protocol="HTTP/1.1"
maxHttpHeaderSize="8192"
maxThreads="500" minSpareThreads="250"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"
acceptorThreadCount="2" />
我尝试使用 this tutorial 更改 ulimit 我能够为运行 tomcat 的用户更改打开文件描述符的硬限制,但它没有解决问题,应用程序仍然挂起。
上次我不得不重新启动服务器,它运行了大约 3 个小时,我有这些打开连接的值:
lsof -p TOMCAT_PID | wc -l
632 (more or less!! i did not write the exact number)
这个数字突然开始增长。
我在其他服务器上有一些与这个非常相似的应用程序,不同之处在于它们是独立版本,这是一个多租户架构,我注意到在这个应用程序中我得到了这些类型的套接字连接,它们没有t 出现在任何其他安装的独立版本中:
java 11506 root 646u IPv6 136862 0t0 TCP lixxx-xxx.members.linode.com:www->180.76.6.16:49545 (ESTABLISHED)
java 11506 root 647u IPv6 136873 0t0 TCP lixxx-xxx.members.linode.com:www->50.31.164.139:37734 (CLOSE_WAIT)
java 11506 root 648u IPv6 135889 0t0 TCP lixxx-xxx.members.linode.com:www->ec2-54-247-188-179.eu-west-1.compute.amazonaws.com:28335 (CLOSE_WAIT)
java 11506 root 649u IPv6 136882 0t0 TCP lixxx-xxx.members.linode.com:www->ec2-54-251-34-67.ap-southeast-1.compute.amazonaws.com:19023 (CLOSE_WAIT)
java 11506 root 650u IPv6 136884 0t0 TCP lixxx-xxx.members.linode.com:www->crawl-66-249-75-113.googlebot.com:39665 (ESTABLISHED)
java 11506 root 651u IPv6 136886 0t0 TCP lixxx-xxx.members.linode.com:www->190.97.240.116.viginet.com.ve:1391 (ESTABLISHED)
java 11506 root 652u IPv6 136887 0t0 TCP lixxx-xxx.members.linode.com:www->ec2-50-112-95-211.us-west-2.compute.amazonaws.com:19345 (ESTABLISHED)
java 11506 root 653u IPv6 136889 0t0 TCP lixxx-xxx.members.linode.com:www->ec2-54-248-250-232.ap-northeast-1.compute.amazonaws.com:51153 (ESTABLISHED)
java 11506 root 654u IPv6 136897 0t0 TCP lixxx-xxx.members.linode.com:www->baiduspider-180-76-5-149.crawl.baidu.com:31768 (ESTABLISHED)
java 11506 root 655u IPv6 136898 0t0 TCP lixxx-xxx.members.linode.com:www->msnbot-157-55-32-60.search.msn.com:35100 (ESTABLISHED)
java 11506 root 656u IPv6 136900 0t0 TCP lixxx-xxx.members.linode.com:www->50.31.164.139:47511 (ESTABLISHED)
java 11506 root 657u IPv6 135924 0t0 TCP lixxx-xxx.members.linode.com:www->ec2-184-73-237-85.compute-1.amazonaws.com:28206 (ESTABLISHED)
我猜它们是某种自动连接。
所以我的问题是:
我如何确定问题是由我的代码、服务器还是某种攻击引起的?您推荐哪种方法来解决这个问题?
提前谢谢你:)
【问题讨论】:
maxThreads="10000" 真的很乐观;) jaja!你是对的,可能忘记在测试后将其设置回来。感谢您指出这一点。 将其更改为 maxThreads="500",并更新了帖子。 :) 【参考方案1】:有点晚了,但对于任何在这个问题上苦苦挣扎的人来说,这可能是一个帮助/提示。我们时不时地遇到同样奇怪的问题(我们的 tomcat 服务每天晚上都会重新启动(它会清理打开的句柄),所以错误不会经常发生)。 我们使用带有 ajp 协议的 apache 代理。问题是错误的协议实现。 我们的连接器配置现在如下:
<Connector
port="8009"
protocol="org.apache.coyote.ajp.AjpNioProtocol"
connectionTimeout="1800000"
acceptorThreadCount="2"
maxThreads="400"
maxConnections="8192"
asyncTimeout="20000"
acceptCount="200"
minSpareThreads="40"
compression="on"
compressableMimeType="text/html,text/xml,text/plain"
enableLookups="false"
URIEncoding="UTF-8"
redirectPort="8443" />
请注意:protocol="org.apache.coyote.ajp.AjpNioProtocol" 这个实现为我们解决了问题——不再需要打开文件句柄。 更多信息可以在这里找到:https://itellity.wordpress.com/2013/07/12/getting-rid-of-close_waits-in-tomcat-67-with-mod_proxy/ 我希望这可以帮助别人。 祝你有美好的一天!
【讨论】:
【参考方案2】:好的,原来是jdbc连接设置的问题,maxActive设置为20个连接,我把限制改成200,问题就解决了。
我认为这是问题所在,这要归功于 appdynamics.com 的出色工具,它可以让您检查 ApplicationInfraestructurePerformance 指标中的大量指标。
另外,发现这篇关于帮助我调整我的应用程序的主题的精彩文章:
http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency
官方文档也有帮助:
https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html.
我猜想到达的连接首先启动了一个查询,该查询首先破坏了服务器的响应能力,然后填充了操作系统套接字限制,在 linux 中,打开的套接字是打开的文件。我希望这对某人有帮助!
编辑
你好!这个解决方案在短期内解决了这个问题,但是出现了另一个关于 JDBC 连接的错误,应用程序没有关闭连接,我打开并解决了一个关于这个问题的票 here
【讨论】:
【参考方案3】:您是否检查过您的ulimit
是否有正在运行tomcat 的用户?
默认情况下,Linux 有 1024 个打开文件的限制。
更多关于
How do I change the number of open files limit in Linux?
有可能你的配置中有太多的连接,或者由于某种原因你没有正确关闭一些 IO 流(极不可能)。
我会通过增加ulimit
来接近它,然后运行一些负载测试以查看文件使用量激增的原因。
【讨论】:
你好 Mite,谢谢你的回答......我确实改变了 ulimit,我在原始帖子中写了关于它,在 server.xml 连接器描述之后。我将它提高到 65535。我没有收到那个错误,但是 Tomcat 停止响应,并且打开的文件正在上升。如果我不管它,我可能会得到那个错误,但必须重新启动。我尝试使用 jmeter 进行负载测试,如果我每秒发出大量请求,它会减慢速度,但我不确定如何检测导致它的原因。 当你运行 lsof -p TOMCAT_PID 时打开了哪些文件、连接或其他什么? 你好,Mite,主要是连接,我认为来自机器人和网络爬虫。我刚刚制作了一个脚本,它会在发生这种情况时进行监视并记录 -p TOMCAT_PID 的输出,因此我可以给你一个准确的答案。再次感谢您的回答。我会尽快更新更多信息以上是关于java.net.SocketException:Spring Hibernate Tomcat 打开的文件太多的主要内容,如果未能解决你的问题,请参考以下文章
是啥导致我的 java.net.SocketException:连接重置? [复制]
如何修复 java.net.SocketException:损坏的管道?
Java 1.6 HttpsURLConnection:java.net.SocketException:连接重置
java.net.SocketException:recvfrom 失败:ETIMEDOUT(连接超时)