如何解决错误java.net.SocketException:打开的文件过多 [英] How to resolve the error java.net.SocketException: Too many open files

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

问题描述



使用1000个并发用户时遇到以下错误:

$ b使用JMeter为我的REST API进行负载测试。
$ b

 打开的文件过多。 Stacktrace如下:
java.net.SocketException:太多打开的文件
在java.net.Socket.createImpl(Socket.java:397)
在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)$在org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)上的
$ b 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)
在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中打开文件的数量?



是我对另一台服务器进行的调用



pre $ Map getResponse(Map data,String url){
HTTPBuilder httpBuilder =新的HTTPBuilder(url);
httpBuilder.request(Method.POST,JSON){
headers.'Authorization'= AppConfig.config.appKey;
headers.'Content-type'='application / json'
body = data
response.success = {resp,reader - >
返回读者为地图;
}
response.failure = {response,reader - >
return null
}
}
}


解决方案

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



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

  ulimit -n 

From here


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



正确的解决方案是将套接字关闭在正确的
时间(我猜是服务器在连接结束时关闭
时)。这对HttpURLConnection来说似乎很难。
这一切都很混乱:


  • disconnect()似乎立即关闭 - 或者不是;
    Javadocs故意模糊了它实际上
    所做的事情,特别是当它实际执行时。


  • close()可能是正确的选择。
    Java错误#4147525的评估部分说:...在输入和/或
    输出流中调用close()。这将正确地导致底层
    套接字在你不会做keepalive
    连接,并且会正确地缓存并重新使用keepalive
    连接(并且会在短时间内超时并关闭自己
    )。


  • 但也许不是。 Bug#4142971说:调用close()
    方法对于
    底层HTTP连接是否持久无效。




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



也许真正的答案是放弃HttpURLConnection,而
使用Jakarta Commons的HTTP Client。有人建议,在
连接中有另一个问题(bug
#4143518 )。


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

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)

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

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

解决方案

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 

From here:

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.

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() 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() 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)."

  • 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."

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.

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:打开的文件过多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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