我正在使用Java的InetAddress.getHostName()
执行一些反向 DNS 查找,但它所花费的时间似乎有问题。这是一个代码片段:
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));
}
}
这是我机器上的输出:
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
无论我运行此代码多少次,解析 10.0.0.138 和 216.239.49.245 都需要 4.5 秒。所有无法解析的 IP 地址似乎都会发生这种情况。
这不是网络问题,因为根据wireshark捕获,DNS查询甚至没有发送当这段代码运行时除非先清除DNS缓存(然后结果甚至更慢 - 每个分辨率大约 4.7 秒)。
那么 Java 是否真的需要 4.5 秒才能针对操作系统的本地 DNS 缓存超时?这是没有意义的。命令行实用程序nslookup
返回这些 IP 地址的(无法解析的)结果要快得多,而且它甚至不使用缓存!
有人可以解释这种行为并提出加快这些解决方案的方法吗?在不求助于外部库的情况下,我唯一能想到的就是使用多个线程,因此至少 4.5 秒的超时将并行执行。
作为参考,我在 Windows 7 x64 上使用 JDK 7u71
Edit1:
This问题似乎相关,但那里的答案说性能取决于网络,这不是我观察到的。
Edit2:
这似乎是一个windows问题。同一 LAN 中的一台计算机使用完全相同的 DNS,运行 OpenSuse 13.1 和 JDK 1.7u67 返回以下结果:
没有 DNS 缓存:
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
使用 DNS 缓存:
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:
最终我不得不通过使用我自己的反向 DNS 查找来解决这个问题dnsjava.