java.net.SocketException: 太多打开的文件 Spring Hibernate Tomcat

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23252974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:31:52  来源:igfitidea点击:

java.net.SocketException: Too many open files Spring Hibernate Tomcat

javaspringhibernatetomcatnginx

提问by Ernest

I have a Hibernate, Spring, Debian, Tomcat, MySql stack on a Linode server in production with some clients. Its a Spring-Multitenant application that hosts webpages for about 30 clients.

我在一些客户端的生产中的 Linode 服务器上有一个 Hibernate、Spring、Debian、Tomcat、MySql 堆栈。它是一个 Spring-Multitenant 应用程序,可为大约 30 个客户端托管网页。

The applications starts fine, then after a while, Im getting this error:

应用程序启动正常,然后过了一会儿,我收到此错误:

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)

Before this error is thrown however, nagios alerts me that pings to the server stop responding.

然而,在抛出此错误之前,nagios 会提醒我对服务器的 ping 停止响应。

Previously, I had nginx as a proxy, and was getting this nginx errors per request instead, and had to restart tomcat anyway:

以前,我使用 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"

This is my server.xml Connector configuration:

这是我的 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" />

I tried changing the ulimit using this tutorialI was able to change the hard limit for opened file descriptors for the user running tomcat, but it did not fix the problem, the application still hangs.

我尝试使用本教程更改 ulimit我能够为运行 tomcat 的用户更改打开文件描述符的硬限制,但它没有解决问题,应用程序仍然挂起。

The last time that I had to restart the server, It ran for about 3 hours, I had these values for socked opened connections:

上次我不得不重新启动服务器时,它运行了大约 3 个小时,我为已打开的连接设置了这些值:

lsof -p TOMCAT_PID | wc -l
632 (more or less!! i did not write the exact number)

This numbers suddenly starts growing.

这个数字突然开始增长。

I have some applications very similar to this one on other servers, the difference is that they are a Stand Alone version and this is a Multitenant architecture, I notice that in this app Im getting these kind of socket connections, which don't occur in the Stand Alone version of any of the other installations:

我有一些与其他服务器上的应用程序非常相似的应用程序,不同之处在于它们是独立版本,这是一个多租户架构,我注意到在这个应用程序中我得到了这些类型的套接字连接,这不会发生在任何其他安装的独立版本:

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)

They are some kind of automated connections I guess.

我猜它们是某种自动连接。

So my question is:

所以我的问题是:

How can I determine if the problem is because of my code, server, or some kind of attack and which approach would you recommend to figure this out ?

我如何确定问题是由于我的代码、服务器还是某种攻击引起的,您会推荐哪种方法来解决这个问题?

Thank you in Advance :)

先感谢您 :)

采纳答案by Ernest

Ok, it turns out that the problem was the jdbc connection settings, has maxActive set to 20 connections, I changed the limit to 200 and the problem stopped.

好吧,原来是jdbc连接设置的问题,把maxActive设置为20个连接,我把限制改成200,问题就解决了。

The way I figured this was the problem was thanks to appdynamics.com′s wonderful tool, which lets you check a great deal of metrics in the ApplicationInfraestructurePerformance metrics.

我认为这是问题所在的方式要归功于 appdynamics.com 的出色工具,它可以让您检查 ApplicationInfraestructurePerformance 指标中的大量指标。

Also, found this wonderful article about the subject which helped me tune my app:

另外,找到了这篇关于这个主题的精彩文章,它帮助我调整了我的应用程序:

http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency

http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency

the oficial documentation also helped:

官方文件也有帮助:

https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html.

https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

I guess that the arriving connections started a query which collapsed the server response ability first, and afterwards filled the OS socket limits, in linux, open socket are open files. I hope this helps someone !

我猜到达的连接开始了一个查询,它首先崩溃了服务器响应能力,然后填充了操作系统套接字限制,在 linux 中,打开的套接字是打开的文件。我希望这可以帮助别人 !

EDIT

编辑

Hello! This solution solved the issue in the short term, but another error regarding the JDBC connection appeared, the application was not closing the connections, I opened and solved a ticket regarding that issue here

你好!这个解决方案在短期内解决了这个问题,但出现了另一个关于 JDBC 连接的错误,应用程序没有关闭连接,我在这里打开并解决了关于该问题的票证

回答by Mite Mitreski

Have you checked your ulimitfor the user that is running tomcat? Linux has a limit of 1024 open files by default. More on How do I change the number of open files limit in Linux?

您是否检查ulimit过正在运行 tomcat 的用户?默认情况下,Linux 有 1024 个打开文件的限制。更多关于 如何更改 Linux 中打开文件的数量限制?

There is a possibility you have too many connections in the configs or for some reason you are not properly closing some IO streams(higly unlikely).

您可能在配置中有太多连接,或者由于某种原因您没有正确关闭某些 IO 流(极不可能)。

I would approach it by increasing the ulimitand then run some load test to see what is spiking the file usage.

我会通过增加ulimit然后运行一些负载测试来查看是什么导致文件使用量激增。

回答by Thomas Lang

a bit late, but maybe a help/hint for anyone struggling with this issue. we had the same strange problem every now and then (our tomcat service is restarted every day at night (which cleans the open handles), so the error was not happening that often).
We use a apache proxy with ajp protocol. The problem was a wrong protocol implementation.
Our connector config is now the following:

有点晚了,但对于任何在这个问题上挣扎的人来说,这可能是一个帮助/提示。我们时不时遇到同样的奇怪问题(我们的 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" />

Please mind this: protocol="org.apache.coyote.ajp.AjpNioProtocol"
This implementation did the trick for us - no more open file handles. Further information can be found here: https://itellity.wordpress.com/2013/07/12/getting-rid-of-close_waits-in-tomcat-67-with-mod_proxy/
I hope this helps someone. Have a nice day!

请注意这一点:protocol="org.apache.coyote.ajp.AjpNioProtocol"
这个实现对我们起到了作用——不再有打开的文件句柄。可以在此处找到更多信息:https: //itellity.wordpress.com/2013/07/12/getting-rid-of-close_waits-in-tomcat-67-with-mod_proxy/
我希望这对某人有所 帮助。祝你今天过得愉快!