JVM 和操作系统 DNS 缓存

2022-09-04 23:05:15

我遇到了JVM和DNS的问题。

我正在阅读的所有内容(包括文档本文)都说我可以使用 禁用 JVM DNS 缓存,这可以使用 来设置,但可以通过使用系统属性的标准方法进行设置。我已经成功地将其更改为0,因此在我的JVM中不再缓存。networkaddress.cache.ttljava.security.Security.setProperties

但是现在,在每次调用时,似乎我的JVM正在使用系统DNS缓存(在我的情况下是Windows 8)。实际上,在对该方法的2次调用之间,我已经将BIND9属性更改为“mytest.com”,但IP返回仍然相同。工作流程如下:InetAddress.getByName("mytest.com")

  1. setCachePolicyInJVM(0)在我的Java代码中。
  2. 设置为 192.168.1。188 在 BIND9 中,重新启动。mytest.com
  3. InetAddress.getByName("mytest.com").getHostAddress();-> 192.168.1.189
  4. 设置 -> 192.168.1。在 BIND9 中为 160,重新启动。mytest.com
  5. InetAddress.getByName("mytest.com").getHostAddress();-> 192.168.1.188(如果没有缓存,则应为 160)。
  6. 刷新 Windows DNS
  7. InetAddress.getByName("mytest.com").getHostAddress();-> 192.168.1.159

我已经多次读到JVM不使用系统缓存,但这是错误的:它显然使用。

我们如何绕过操作系统 DNS 缓存,在每次调用时强制使用新的 DNS 解析?


答案 1

我想我遇到了这个问题,或者一个非常相似的问题。我当时所做的是为JVM实现我自己的DNS提供商,请参阅如何更改java dns服务提供商以获取详细信息。您可以使用那里提到的 dnsjava 或滚动自己的 dnsjava。


答案 2

您可以编辑 for Java 6-8 和属性文件以添加以下属性。$JAVA_HOME/jre/lib/security/java.security$JAVA_HOME/conf/security/java.security

networkaddress.cache.ttl=1

在命令行中设置它不可用。

由于这 2 个属性是安全策略的一部分,因此它们不是由 -D 选项或 System.setProperty() API 设置的,而是设置为安全属性。

若要在代码中设置此属性,可以使用以下方法。

java.security.Security.setProperty("networkaddress.cache.ttl", "1")

或者在 java 命令行中添加以下属性。

-Dnetworkaddress.cache.ttl=1

同样重要的是要注意,仅当未设置相应的属性时,值才有效。networkaddress.cache.*

有关更多详细信息,请参阅 Java 8 网络属性、Java 9 网络属性Java 虚拟机中的 VeriSign DNS 缓存

这个答案还增加了一些细节。