我正在使用Java的HttpUrlConnection来点击foo.com
foo.com有多个指向不同IP地址的A-Records(1.1.1.1和1.1.1.2)
如果我的第一个连接呼叫解析为1.1.1.1,但随后该机器出现故障,后续的连接呼叫会识别出这个并尝试连接1.1.1.2吗?
或者我是否需要使用INetAddress api自己实现这种逻辑?
答案 0 :(得分:8)
我可以使用Apache Commons HttpClient解决此问题,请参阅下面的代码段。
就像我担心的那样,java.net提供的URLConnection是一个非常简单的实现,只会尝试解析列表中的第一个IP地址。如果您真的不允许使用其他库,则必须编写自己的错误处理。它有点混乱,因为您需要先使用InetAddress解析所有IP,然后连接到每个IP,将“Host:domain.name”标头传递给HTTP堆栈,直到其中一个IP响应。
Apache库非常强大,可以进行大量自定义。您可以控制它重试的次数,最重要的是,它会自动尝试解析为同名的所有IP地址,直到其中一个成功响应。
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int count, HttpContext context) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
return count < 30;
}
};
ConnectionKeepAliveStrategy keepAlive = new ConnectionKeepAliveStrategy() {
@Override
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
return 500;
}
};
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter("http.socket.timeout", new Integer(2000));
httpclient.getParams().setParameter("http.connection.timeout", new Integer(2000));
httpclient.setHttpRequestRetryHandler(myRetryHandler);
httpclient.setKeepAliveStrategy(keepAlive);
HttpGet httpget = new HttpGet("http://remotehost.com");
HttpResponse httpres = httpclient.execute(httpget);
InputStream is = httpres.getEntity().getContent();
我希望这有帮助!