I'm using Java's InetAddress.getHostName()
to perform some reverse DNS lookups, and something seems wrong with the time it takes. Here's a code snippet:
public static void main(String[] args) throws IOException {
byte[][] addresses = new byte[][] { { 10, (byte) 0, (byte) 0, (byte) 138 }
, new byte[] { (byte) 216, (byte) 239, (byte) 49, (byte) 245 }
,{ 8, (byte) 8, (byte) 8, (byte) 8 } };
for (byte[] addr : addresses) {
InetAddress inet = InetAddress.getByAddress(addr);
long before = System.currentTimeMillis();
String hostName = inet.getHostName();
System.out.printf("%20s %40s %5d\n", inet.getHostAddress(), hostName, (System.currentTimeMillis() - before));
}
}
And here's the output on my machine:
10.0.0.138 10.0.0.138 4503
216.239.49.245 216.239.49.245 4591
8.8.8.8 google-public-dns-a.google.com 8
Resolving both 10.0.0.138 and 216.239.49.245 takes 4.5 seconds each, regardless of the number of times I've ran this code. This seems to happen with all unresolvable IP addresses.
This isn't a networking issue since according to a wireshark capture, DNS queries aren't even sent when this code is run unless the DNS cache is cleared first (and then the results are even slower - around 4.7 seconds per resolution).
So does it actually take Java 4.5 seconds to timeout against the OS's local DNS cache? That makes no sense. The command line utility nslookup
returns (unresolvable) results for these IP addresses much faster, and it doesn't even use the cache!
Can some one explain this behavior and suggest way to speed up these resolutions? The only thing I can think of without turning to external libraries is using multiple threads so at least the 4.5 second timeout will be executed in parallel.
For reference, I'm using JDK 7u71 on Windows 7 x64
Edit1: This question seems relevant, but the answer there says that the performance depends on the network, which is not what I observed.
Edit2:
This seems to be a windows issue. A machine in the same LAN, that uses the exact same DNS, running OpenSuse 13.1 with JDK 1.7u67 returned the following results:
Without DNS caching:
10.0.0.138 10.0.0.138 116
216.239.49.245 216.239.49.245 5098
8.8.8.8 google-public-dns-a.google.com 301
With DNS caching:
10.0.0.138 10.0.0.138 5
216.239.49.245 216.239.49.245 9
8.8.8.8 google-public-dns-a.google.com 40
Edit3:
Eventually I had to work around the issue by doing my own reverse DNS lookups using dnsjava.