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

发布于 2024-10-31 19:47:22 字数 2010 浏览 0 评论 0原文

我有一个java应用程序,它运行得很好(在Ubuntu 10.04上)几个小时,直到它遇到“java.net.SocketException:打开文件太多”。 Sender.java 的代码可以找到 这里

是因为我为每个线程创建了一个HttpPutHttpPost的新实例吗?我正在使用 apache-commons HTTPClient 4。

这是异常日志:

java.net.SocketException: Too many open files
    at java.net.Socket.createImpl(Socket.java:414)
    at java.net.Socket.connect(Socket.java:544)
    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:133)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
    at com.marketplace.io.Sender.doBasicHttpPost(Sender.java:434)
    at com.marketplace.io.Sender.appVisualExists(Sender.java:223)
    at com.marketplace.io.Sender.addVisualToCollection(Sender.java:350)
    at com.marketplace.service.ImageThread.run(ImageThread.java:136)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:636)

I have a java app which runs just fine (on Ubuntu 10.04) for few hours until it hits "java.net.SocketException: Too many open files". The code for Sender.java can be found here

Is it because I create a new instance of HttpPut and HttpPost for each thread? I'm using apache-commons HTTPClient 4.

Here's the exception log:

java.net.SocketException: Too many open files
    at java.net.Socket.createImpl(Socket.java:414)
    at java.net.Socket.connect(Socket.java:544)
    at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:133)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
    at com.marketplace.io.Sender.doBasicHttpPost(Sender.java:434)
    at com.marketplace.io.Sender.appVisualExists(Sender.java:223)
    at com.marketplace.io.Sender.addVisualToCollection(Sender.java:350)
    at com.marketplace.service.ImageThread.run(ImageThread.java:136)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:636)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

≈。彩虹 2024-11-07 19:47:22

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

请注意,套接字连接被视为文件,并且它们使用文件描述符,这是一种有限的资源。

不同的操作系统对其可以管理的文件句柄数量有不同的限制。

简而言之,出现此错误是因为客户端频繁连接和断开连接。如果您想在自己这边处理它,您有两个选择:

1) 增加每个进程打开的文件句柄或文件描述符的数量。

在基于 UNIX 的操作系统中,例如 Ubuntu 或 Solaris,您可以使用命令 ulimit -a 来了解每个进程允许打开的文件句柄数。

$ ulimit -a
core file size        (blocks, -c) unlimited
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
open files                    (-n) 256
pipe size          (512 bytes, -p) 10
stack size            (kbytes, -s) 8192
cpu time             (seconds, -t) unlimited
max user processes            (-u) 2048
virtual memory        (kbytes, -v) unlimited

可以看到,打开文件 (-n) 256,这意味着每个进程只允许打开 256 个文件句柄。如果你的Java程序,记住Tomcat,weblogic或任何其他应用服务器都是Java程序并且它们在JVM上运行,超过这个限制,它将抛出java.net.SocketException: Too much files open错误。

您可以使用 ulimit -n 将此限制更改为更大的数字,例如 4096,但请遵循 UNIX 系统管理员的建议,并且如果您有单独的 UNIX 支持团队,则最好升级给他们。

2) 减少操作系统中 TIME_WAIT 状态的超时

在基于 UNIX 的系统中,您可以在 /proc/sys/net/ipv4/tcp_fin_timeout 文件中查看当前配置。

在基于Windows的系统中,您可以在Windows注册表中看到此信息。您可以按照以下步骤更改 Windows 中的 TCPTIME_WAIT 超时:

1) Open Windows Registry Editor, by typing regedit in run command window
2) Find the key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters
3) Add a new key value pair TcpTimedWaitDelay asa decimal and set the desired timeout in seconds (60-240)
4) Restart your windows machine.

"java.net.SocketException: Too many files open"can be seen any Java Server application e.g. Tomcat, Weblogic, WebSphere etc, with client connecting and disconnecting frequently.

Please note that socket connections are treated like files and they use file descriptor, which is a limited resource.

Different operating system has different limits on number of file handles they can manage.

In short, this error is coming because clients are connecting and disconnecting frequently.If you want to handle it on your side, you have two options :

1) Increase number of open file handles or file descriptors per process.

In UNIX based operating system e.g. Ubuntu or Solaris, you can use command ulimit -a to find out how many open file handles per process is allowed.

$ ulimit -a
core file size        (blocks, -c) unlimited
data seg size         (kbytes, -d) unlimited
file size             (blocks, -f) unlimited
open files                    (-n) 256
pipe size          (512 bytes, -p) 10
stack size            (kbytes, -s) 8192
cpu time             (seconds, -t) unlimited
max user processes            (-u) 2048
virtual memory        (kbytes, -v) unlimited

You can see that, open files (-n) 256, which means only 256 open file handles per process is allowed. If your Java program, remember Tomcat, weblogic or any other application server are Java programs and they run on JVM, exceeds this limit, it will throw java.net.SocketException: Too many files open error.

You can change this limit by using ulimit -n to a larger number e.g. 4096, but do it with advise of UNIX system administrator and if you have separate UNIX support team, than better escalate to them.

2) Reduce timeout for TIME_WAIT state in your operating system

In UNIX based systems, you can see current configuration in /proc/sys/net/ipv4/tcp_fin_timeout file.

In Windows based system, you can see this information in windows registry. You can change the TCPTIME_WAIT timeout in Windows by following below steps :

1) Open Windows Registry Editor, by typing regedit in run command window
2) Find the key HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\tcpip\Parameters
3) Add a new key value pair TcpTimedWaitDelay asa decimal and set the desired timeout in seconds (60-240)
4) Restart your windows machine.
旧时光的容颜 2024-11-07 19:47:22

在第 438 行,您以流形式获取响应并将其转换为字节数组。由entity.getContent()返回的InputStream不会被关闭。这可能是导致问题的原因之一。另外, 由于相关原因,HttpEntity.consumeContent() 已被弃用。

On line 438 you get the response as a stream and convert that to a byte array. The InputStream returned by entity.getContent() does not get closed. This could be contributing to the problem. Also, the HttpEntity.consumeContent() is deprecated for related reasons.

缺⑴份安定 2024-11-07 19:47:22

您可能还想检查 Linux 最大打开文件限制。此相关链接用于定制基于 java 的产品,但它很好地解释了解决问题所需的步骤。

You might also want to check the linux maximum open file limit. This related link is for a bespoke java-based product but it nicely explains the steps required to fix the issue.

泪意 2024-11-07 19:47:22

(已解决)

我最近遇到了同样的错误,因为数据库服务器上的 var/log 已满。

#df -h
S.ficheros            Size  Used Avail Use% Montado en

/dev/cciss/c0d0p3     126G  126G    0G 100% /var


#echo "">/var/log/postgresql/postgresql.log

现在,错误消失了!

重要:查看 postgresql.log 中记录的内容,查看 postgresql.conf

再见
@_jpgo

(RESOLVED)

I recently have the same error because the var/log on DataBase Server is Full.

#df -h
S.ficheros            Size  Used Avail Use% Montado en

/dev/cciss/c0d0p3     126G  126G    0G 100% /var


#echo "">/var/log/postgresql/postgresql.log

Now, the error is gone!!!

important: see what to log in postgresql.log, review your postgresql.conf

bye
@_jpgo

∞琼窗梦回ˉ 2024-11-07 19:47:22

我通过在finally块中关闭连接解决了这个问题。

public  static String postMethod(String jsonStr,String sendUrl){
    String resultJson = "";
    HttpClient httpClient = new HttpClient();
    PostMethod post = new PostMethod(sendUrl);
    post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");  
    NameValuePair[] param = { new NameValuePair("message",jsonStr)} ;
    post.setRequestBody(param);
    try {
        httpClient.executeMethod(post);
        resultJson = post.getResponseBodyAsString();
    } catch (HttpException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
         post.releaseConnection();
         ((SimpleHttpConnectionManager)httpClient.getHttpConnectionManager()).shutdown();
    }
    return resultJson;
}

I solve the problem by closing the connection in the finally block。

public  static String postMethod(String jsonStr,String sendUrl){
    String resultJson = "";
    HttpClient httpClient = new HttpClient();
    PostMethod post = new PostMethod(sendUrl);
    post.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");  
    NameValuePair[] param = { new NameValuePair("message",jsonStr)} ;
    post.setRequestBody(param);
    try {
        httpClient.executeMethod(post);
        resultJson = post.getResponseBodyAsString();
    } catch (HttpException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }finally{
         post.releaseConnection();
         ((SimpleHttpConnectionManager)httpClient.getHttpConnectionManager()).shutdown();
    }
    return resultJson;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文