java.net.SocketException : Too many open files 异常

标签 java apache-httpclient-4.x

我有一个 Java 应用程序可以正常运行(在 Ubuntu 10.04 上)几个小时,直到它出现“java.net.SocketException:打开的文件太多”。可以找到 Sender.java 的代码 here

是因为我为每个线程创建了一个新的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)

最佳答案

“java.net.SocketException:打开的文件太多”可以在任何 Java 服务器应用程序中看到,例如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

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

您可以使用 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 open files 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5656458/

相关文章:

java - Android - 无法向上滚动

java - 如何正确映射与@IdClass的多对一关系?

java - GitHub API 速率限制不超过 Apache HttpClient

java - 如果只绘制特定区域,为什么需要调用两次重绘?

java - java 是否有一个简约的 WebSocket 客户端库?

java - 单击 JavaFX ListView 中的任意位置将返回索引 -1 并崩溃

java - 处理 HttpClient (Httpget) 超时

java - Uber API - 在沙盒中请求乘车 - 接收错误 : Invalid request - validation_failed

java - 如何使用 Apache HttpClient 4 添加对已弃用的 SSL 密码套件的支持

java - Apache HttpClient : How to auto close connections by server's keep-alive time?