gpt4 book ai didi

java - BindException/在负载下使用 HttpClient 时打开的文件过多

转载 作者:搜寻专家 更新时间:2023-10-31 20:07:17 26 4
gpt4 key购买 nike

我有 1000 个专用 Java 线程,每个线程每一秒轮询一个相应的 url。

public class Poller { 
public static Node poll(Node node) {
GetMethod method = null;
try {
HttpClient client = new HttpClient(new SimpleHttpConnectionManager(true));
......
} catch (IOException ex) {
ex.printStackTrace();
} finally {
method.releaseConnection();
}
}
}

线程每隔一秒运行一次:

for (int i=0; i <1000; i++) { 
MyThread thread = threads.get(i) // threads is a static field
if(thread.isAlive()) {
// If the previous thread is still running, let it run.
} else {
thread.start();
}
}

问题是,如果我每隔一秒运行一次作业,就会出现如下随机异常:

java.net.BindException: Address already in use 
INFO httpclient.HttpMethodDirector: I/O exception (java.net.BindException) caught when processing request: Address already in use
INFO httpclient.HttpMethodDirector: Retrying request

但如果我每 2 秒或更长时间运行一次作业,一切都会正常运行。

我什至尝试使用 shutDown() 关闭 SimpleHttpConnectionManager() 实例,但没有任何效果。

如果我执行 netstat,我会看到数千个 TCP 连接处于 TIME_WAIT 状态,这意味着它们已关闭并正在清理。

所以为了限制连接数,我尝试使用 HttpClient 的单个实例并像这样使用它:

  public class MyHttpClientFactory { 
private static MyHttpClientFactory instance = new HttpClientFactory();
private MultiThreadedHttpConnectionManager connectionManager;
private HttpClient client;

private HttpClientFactory() {
init();
}

public static HttpClientFactory getInstance() {
return instance;
}

public void init() {
connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams managerParams = new HttpConnectionManagerParams();
managerParams.setMaxTotalConnections(1000);
connectionManager.setParams(managerParams);
client = new HttpClient(connectionManager);
}

public HttpClient getHttpClient() {
if (client != null) {
return client;
} else {
init();
return client;
}
}
}

然而,在刚好运行 2 小时后,它开始抛出“太多打开的文件”,最终什么也做不了。

ERROR java.net.SocketException: Too many open files
INFO httpclient.HttpMethodDirector: I/O exception (java.net.SocketException) caught when processing request: Too many open files
INFO httpclient.HttpMethodDirector: Retrying request

我应该能够增加允许的连接数并使其工作,但我只会延长邪恶。知道在上述情况下使用 HttpClient 的最佳做法是什么吗?

顺便说一句,我还在使用 HttpClient3.1。

最佳答案

这件事几个月前发生在我们身上。首先,仔细检查以确保您确实每次都在调用 releaseConnection()。但即便如此,操作系统实际上并没有立即回收所有 TCP 连接。解决方案是使用 Apache HTTP 客户端的 MultiThreadedHttpConnectionManager .这汇集并重用连接。

参见 http://hc.apache.org/httpclient-3.x/performance.html获取更多性能提示。

更新:糟糕,我没有阅读下面的代码示例。如果您正在执行 releaseConnection() 并使用 MultiThreadedHttpConnectionManager,请考虑您的操作系统对每个进程打开文件的限制是否设置得足够高。我们也遇到了这个问题,需要稍微扩大限制。

关于java - BindException/在负载下使用 HttpClient 时打开的文件过多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2914218/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com