Java Httpurlconnection 具有多个IP地址的DNS解析

发布于 2024-12-05 07:37:07 字数 232 浏览 1 评论 0原文

我正在使用 Java 的 HttpUrlConnection 访问 foo.com

foo.com 有多个指向不同 IP 地址的 A 记录(1.1.1.1 和 1.1.1.2)

如果我的第一个连接调用解析为 1.1.1.1,但随后该机器出现故障down,后续的 connect 调用会识别到这一点并尝试连接 1.1.1.2 吗?

或者我是否需要使用 INetAddress api 自己实现这种逻辑?

I'm using Java's HttpUrlConnection to hit foo.com

foo.com has multiple A-Records that point to different IP addresses (1.1.1.1 and 1.1.1.2)

If my first connect call resolves to 1.1.1.1, but then that machine goes down, will a subsequent connect call recognize this and try to connect on 1.1.1.2 instead?

Or do I need to implement this sort of logic myself using the INetAddress api?

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

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

发布评论

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

评论(1

满栀 2024-12-12 07:37:08

我能够使用 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();

我希望这有帮助!

I was able to resolve this by using Apache Commons HttpClient, see the code snippet below.

Like I feared, the URLConnection provided by java.net is a very simplistic implementation and will only try the first IP address from the resolved list. If you really are not allowed to use another library, you will have to write your own error handling. It's kinda messy, since you will need to resolve all IPs before hand using InetAddress, and connect to each IP passing the "Host: domain.name" header to the HTTP stack yourself until one of the IPs responds.

The Apache library is greatly more robust and allows for a great deal of customization. You can control how many times it will retry and, most importantly, it will automatically try all IP addresses resolved to the same name until one of them responds successfully.

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();

I hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文