<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>I had an AI from Scott through the IC per-entity metadata working
group to look into how Apache HttpClient handles (or not) multiple
A records, such as is typically used in DNS round-robin type
setups. I think this was a question b/c it's common in CDNs.</p>
<p>They have a DnsResolver plugin interface with an API like so:</p>
<p> <tt>InetAddress[] resolve(String host) throws
UnknownHostException;</tt><tt><br>
</tt></p>
<p>which I thought was going to be necessary to customize for
something like this. Note it returns an array of InetAddress.<br>
</p>
<p>Turns out that customization isn't necessary. The default
out-of-the-box behavior of HC, even in the older 4.3.6 version
we're currently on, is that it knows about all the A records for
the requested domain, and if there is a socket connect failure,
tries them in turn. I found an example of this [1] as it relates
to timeout configuration, and I tested it out with a domain I know
has multiple A records. It did try them in order as specified
there:<br>
</p>
<p><tt>DEBUG PoolingHttpClientConnectionManager - Connection
request: [route: {}-><a class="moz-txt-link-freetext" href="http://zoom.us:81">http://zoom.us:81</a>][total kept alive: 0;
route allocated: 0 of 2; total allocated: 0 of 20]</tt><tt><br>
</tt><tt>DEBUG PoolingHttpClientConnectionManager - Connection
leased: [id: 0][route: {}-><a class="moz-txt-link-freetext" href="http://zoom.us:81">http://zoom.us:81</a>][total kept
alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]</tt><tt><br>
</tt><tt>DEBUG MainClientExec - Opening connection
{}-><a class="moz-txt-link-freetext" href="http://zoom.us:81">http://zoom.us:81</a></tt><tt><br>
</tt><tt>DEBUG HttpClientConnectionOperator - Connecting to
zoom.us/52.5.0.4:81</tt><tt><br>
</tt><tt>DEBUG HttpClientConnectionOperator - Connect to
zoom.us/52.5.0.4:81 timed out. Connection will be retried using
another IP address</tt><tt><br>
</tt><tt>DEBUG HttpClientConnectionOperator - Connecting to
zoom.us/54.86.107.98:81</tt><tt><br>
</tt><tt>DEBUG DefaultManagedHttpClientConnection -
http-outgoing-0: Shutdown connection</tt><tt><br>
</tt><tt>DEBUG MainClientExec - Connection discarded</tt><tt><br>
</tt><tt>DEBUG DefaultManagedHttpClientConnection -
http-outgoing-0: Close connection</tt><tt><br>
</tt><tt>DEBUG PoolingHttpClientConnectionManager - Connection
released: [id: 0][route: {}-><a class="moz-txt-link-freetext" href="http://zoom.us:81">http://zoom.us:81</a>][total kept
alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]</tt><tt><br>
</tt><tt><br>
</tt><tt>org.apache.http.conn.ConnectTimeoutException: Connect to
zoom.us:81 [zoom.us/52.5.0.4, zoom.us/54.86.107.98] failed:
connect timed out</tt></p>
<p><tt></tt><br>
</p>
<p>I also tried with google.com. They only have 1 IP v4 address in
DNS, but when that failed it then tried the IP v6 address (was
running this locally on a Mac):</p>
<p><tt>DEBUG MainClientExec - Opening connection
{}-><a class="moz-txt-link-freetext" href="http://www.google.com:81">http://www.google.com:81</a></tt><tt><br>
</tt><tt>DEBUG HttpClientConnectionOperator - Connecting to
<a class="moz-txt-link-abbreviated" href="http://www.google.com/216.58.218.4:81">www.google.com/216.58.218.4:81</a></tt><tt><br>
</tt><tt>DEBUG HttpClientConnectionOperator - Connect to
<a class="moz-txt-link-abbreviated" href="http://www.google.com/216.58.218.4:81">www.google.com/216.58.218.4:81</a> timed out. Connection will be
retried using another IP address</tt><tt><br>
</tt><tt>Error from HCDEBUG HttpClientConnectionOperator -
Connecting to <a class="moz-txt-link-abbreviated" href="http://www.google.com/2607:f8b0:4002:806:0:0:0:2004:81">www.google.com/2607:f8b0:4002:806:0:0:0:2004:81</a></tt><tt><br>
</tt><tt>DEBUG DefaultManagedHttpClientConnection -
http-outgoing-0: Shutdown connection</tt><br>
</p>
<p><br>
</p>
<p>At this point I don't know about failure modes other than a
connect timeout, such as a socket timeout once it's connected and
reading data. I wouldn't necessarily expect that to be retried,
but I'm not sure if that's the main use case here.<br>
</p>
<p>But this is at least encouraging and I think a little
surprising. I think our impression was that HTTP client libraries
in general probably didn't do this very well, if at all, and
happily it sounds like in this case, that was incorrect.</p>
<p>--Brent</p>
<p>[1] <a class="moz-txt-link-freetext" href="http://www.baeldung.com/httpclient-timeout">http://www.baeldung.com/httpclient-timeout</a><br>
</p>
</body>
</html>