<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>