Lan*_*ali 5 java apache-commons-httpclient
我有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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
线程每一秒运行一次:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,如果我每隔一秒运行一次该作业,我会得到如下随机异常:
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
Run Code Online (Sandbox Code Playgroud)
但如果我每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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然而,在运行了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
Run Code Online (Sandbox Code Playgroud)
我应该能够增加允许的连接数并使其工作,但我只是在延长邪恶.知道在上述情况下使用HttpClient的最佳做法是什么?
顺便说一下,我还在使用HttpClient3.1.
第一个错误没有任何问题。您刚刚耗尽了可用的经验端口。每个TCP连接可以处于TIME_WAIT状态2分钟。您生成 2000 个/秒。迟早,套接字找不到任何未使用的本地端口,您将收到该错误。TIME_WAIT正是为此目的而设计的。如果没有它,您的系统可能会劫持以前的连接。
第二个错误意味着您打开了太多套接字。在某些系统上,打开文件数有 1K 的限制。也许您只是由于延迟的套接字和其他打开的文件而达到了该限制。在 Linux 上,您可以使用以下命令更改此限制
ulimit -n 2048
Run Code Online (Sandbox Code Playgroud)
但这受到系统范围最大值的限制。