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.