如何解决错误 java.net.SocketException: Too many open files

Posted

技术标签:

【中文标题】如何解决错误 java.net.SocketException: Too many open files【英文标题】:How to resolve the error java.net.SocketException: Too many open files 【发布时间】:2015-07-24 07:07:23 【问题描述】:

我一直在使用 JMeter 对我的 REST API 进行负载测试。

当我遇到 1000 个并发用户时出现以下错误:

Too many open files. Stacktrace follows:
java.net.SocketException: Too many open files
    at java.net.Socket.createImpl(Socket.java:397)
    at java.net.Socket.getImpl(Socket.java:460)
    at java.net.Socket.setSoTimeout(Socket.java:1017)
    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:126)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:476)
    at groovyx.net.http.HTTPBuilder.doRequest(HTTPBuilder.java:441)
    at groovyx.net.http.HTTPBuilder.request(HTTPBuilder.java:390)

我的服务器尝试访问另一个 REST API 来获取数据并对其进行处理,最后返回 JSON 响应。

如何增加 Linux 中打开文件的数量?

以下是我对另一台服务器的调用

Map getResponse(Map data, String url)
    HTTPBuilder httpBuilder = new HTTPBuilder(url);
    httpBuilder.request(Method.POST, JSON) 
        headers.'Authorization' = AppConfig.config.appKey;
        headers.'Content-type' = 'application/json'
        body = data
        response.success =  resp, reader ->
            return reader as Map;
        
        response.failure =  response, reader ->
            return null
        
    

【问题讨论】:

***.com/questions/34588/… 有帮助吗? 文件好像没有关闭。在此处发布您的代码。 可能您创建了很多套接字但没有关闭()它们。我认为 Linux 机器上打开文件和/或套接字的默认最大值是 1024。 @akhil_mittal 好吧……这就是负载测试的重点。该程序假定在任何给定时间都有一千个打开的套接字。 How to solve java.net.SocketException: Too many files open 【参考方案1】:

您肯定打开了最大数量的打开文件/套接字。 Linux 机器上打开文件或套接字的最大数量为 1024。默认情况下。你需要改变它。你可以参考这个java.net.SocketException Too many open files

您可以使用以下查询从您的终端检查以获取允许打开文件的最大数量

ulimit -n 

来自here:

发生的事情是底层套接字没有被关闭, 最终 JVM 碰到了系统的每进程限制 打开文件描述符。

正确的解决方案是使套接字在右侧关闭 时间(我猜是服务器关闭的时间或之后不久 它的连接结束)。使用 HttpURLConnection 似乎很难。 一切都很迷茫:

disconnect() 似乎会立即关闭它——或者不是; Javadocs 故意含糊其辞 确实如此,尤其是在它这样做的时候。

close() 可能是正确的选择。的评估部分 Java bug #4147525 说:“...在输入和/或调用 close() 输出流。这将正确地导致底层 当你不做keepalive时套接字被关闭 连接并将正确缓存和重用keepalive 连接(并且会超时并自行关闭 反正过了一小段时间)。”

但也许不是。错误 #4142971 说:“调用 close() 方法对是否 底层 HTTP 连接是持久的。”

如果没有明确的答案,也许 HttpURLConnection 对象可能是 添加到列表中,并在测试结束时立即断开连接 跑步。这仍然会限制运行的总规模,但至少 丢失的描述符不会在运行之间累积。

也许真正的答案是放弃 HttpURLConnection,而是 使用 Jakarta Commons 的 HTTP 客户端。有人建议在 与不同问题的连接(错误 #4143518)。

【讨论】:

这太棒了。无论我如何使用HttpsUrlConnection 关闭和清理我的连接,我总是遇到“打开的文件太多”。我切换到OkHttp,它几乎开箱即用。我现在假设这是HttpsUrlConnection 中的一个错误。【参考方案2】:

“java.net.SocketException: Too many files open”可以在任何 Java 服务器应用程序中看到,例如Tomcat、Weblogic、WebSphere等,客户端频繁连接断开。

You can find out how to solve "java.net.SocketException: Too many files open" here

【讨论】:

以上是关于如何解决错误 java.net.SocketException: Too many open files的主要内容,如果未能解决你的问题,请参考以下文章

"SQL SERVER,错误:207" 如何解决

如何解决“错误:输入中的语法错误(1)。”

如何解决此分段错误:以下代码的 11 错误?

如何解决子重复错误?

Ftp 错误代码 550,如何解决

这是啥覆盖错误,我该如何解决? [复制]