Forcing Apache HttpClient to detect DNS changes

Viewed 1021

I'm using Apache HTTP client (4.4.x) and I want it to detect that the IP behind the DNS I'm using has changed.

I made this test code:

CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionTimeToLive(5, TimeUnit.SECONDS)
                .build();

        for (int i = 0; i < 1_000; i++) {
            InetAddress address = InetAddress.getByName("devnull-as-a-service.com");
            System.out.println(i + ": HOST header <" + "devnull-as-a-service.com" + "> resolved IP <" + address.getHostAddress() + ">");
            CloseableHttpResponse response = httpClient.execute(new HttpGet("https://devnull-as-a-service.com/dev/null"));
            System.out.println(response.getStatusLine().getStatusCode() + ": " + response.getEntity());

            Thread.sleep(1_000L);
        }

During the test - I change my /etc/hosts and simulate a DNS change.
The output I get is this:

21: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
22: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
23: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
24: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
25: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
26: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
27: HOST header <devnull-as-a-service.com> resolved IP <45.76.95.197>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
28: HOST header <devnull-as-a-service.com> resolved IP <127.0.0.1>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
29: HOST header <devnull-as-a-service.com> resolved IP <127.0.0.1>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]
30: HOST header <devnull-as-a-service.com> resolved IP <127.0.0.1>
200: [Content-Type: text/html; charset=UTF-8,Content-Length: 0,Chunked: false]

Notice that DNS resolution has changed in the 28th iteration but the server is still responding.

When debugging the Http Client code - i see that it reuses the connection in the PoolingHttpClientConnectionManager since it already knows the route.

I was able to mitigate this issue by making the connection pool throw away connections after 5 seconds:

      CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionTimeToLive(5, TimeUnit.SECONDS)
                .build();

This seems to solve the issue, 5 seconds after the DNS change applies - I get routed to the correct host.

My question - is this the correct way of doing this, or is there a better way of detecting route changes while still reusing connections for a long time.

0 Answers
Related