如何解决错误 java.net.SocketException: Too many open files [英] How to resolve the error java.net.SocketException: Too many open files

查看:50
本文介绍了如何解决错误 java.net.SocketException: Too many open files的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been doing load testing for my REST APIs using JMeter.

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

I am getting the following error when hit with 1000 concurrent users:

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 响应.

My server tries to hit another REST API to get the data and process it and finally return a JSON response.

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

How do I increase the number of open files in Linux?

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

Following is the call I am making to another server

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
        }
    }
}

推荐答案

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

You have certainly open the maximum number of open file/sockets. The maximum number of open files or sockets on Linux machines is 1024. by default. You need to change that. You can refer this java.net.SocketException Too many open files

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

You can use below query to check from your terminal to get maximum number of allowed open files

ulimit -n 

来自这里:

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

What's happening is that the underlying sockets aren't being closed, and eventually the JVM bumps into the system's per-process limit on open file descriptors.

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

The right solution would be to make the sockets close at the Right Time (which I guess is when, or shortly after, the server has closed its end of the connection). That seems hard with HttpURLConnection. It's all very confused:

  • disconnect() 似乎立即关闭它——或者不关闭;Javadocs 故意对它的实际内容含糊其辞确实如此,尤其是当它这样做时.

  • disconnect() just seems to close it immediately -- or not; the Javadocs are intentionally vague about what it actually does, and especially when it does it.

close() 可能是正确的选择.评估部分Java 错误 #4147525 说:...在输入和/或输出流.这将正确地导致底层当您不执行 keepalive 时套接字被关闭连接并将正确缓存和重用 keepalive连接(并且会超时并自行关闭无论如何,在很短的时间之后)."

close() might be the right choice. The Evaluation section of Java bug #4147525 says: "... call close() on the input and/or output stream. This will correctly result in the underlying socket being closed when you aren't doing keepalive connections and will correctly cache and reuse keepalive connections (and which will timeout and close themselves after a short time anyway)."

但也许不是.错误 #4142971 说:调用 close()方法不会以一种方式或另一种方式影响底层 HTTP 连接是持久的."

But maybe not. Bug #4142971 says: "Calling the close() methods has no effect one way or the other on whether the underlying HTTP connection is persistent."

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

Failing a clear answer, perhaps the HttpURLConnection objects could be added to a list, and all disconnected at once at the end of the test run. That'd still limit the total size of the run, but at least the lost descriptors wouldn't accumulate between runs.

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

Maybe the real answer is to give up on HttpURLConnection, and instead use the HTTP Client from Jakarta Commons. Someone suggested that in connection with a different problem (bug #4143518).

这篇关于如何解决错误 java.net.SocketException: Too many open files的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆