【问题标题】:JVM and OS DNS CachingJVM 和操作系统 DNS 缓存
【发布时间】:2013-06-26 02:41:14
【问题描述】:

我遇到了 JVM 和 DNS 的问题。

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

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

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

我读过几次,JVM 不使用系统缓存,但这是错误的:它显然是这样做的。

我们如何绕过 OS DNS 缓存,在每次调用时强制执行新的 DNS 解析?

【问题讨论】:

  • 这对我也很有用:我正在尝试禁用 JVM DNS 缓存,以便在故障转移场景期间使用负载均衡器另一端的所有 IP 地址。由于我们处于故障转移场景,我无法提前知道新的 IP 地址,也不清楚新的 IP 地址何时上线。所以我真的需要每次都进行 DNS 查找。

标签: java caching dns jvm


【解决方案1】:

我想我遇到了这个问题,或者一个非常相似的问题。我当时所做的是为 JVM 实现我自己的 DNS 提供程序,有关详细信息,请参阅how to change the java dns service provider。您可以使用那里提到的 dnsjava 或自己滚动。

【讨论】:

  • 您能更改“根”DNS 服务提供商吗?我认为您只能添加在早期提供者为负数时将调用的新提供者。
【解决方案2】:

您可以编辑 $JAVA_HOME/jre/lib/security/java.security for Java 6-8 和 $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 Networking Properties、Java 9 Networking Properties 和 VeriSign DNS Caching in Java Virtual Machines。

这个answer也增加了一些细节。

【讨论】:

  • 在命令行上设置-Dnetworkaddress.cache.ttl=1 不起作用,因为这是一个安全属性而不是系统属性。 sun.net.inetaddr.ttl 至少可以在 java 8 中设置,但是此功能已被弃用。
  • @Nicolas Henneaux 在 Spring Boot 中,使用带有 java.security.Security.setProperty("networkaddress.cache.ttl", "1") 的 @Configuration 类有意义吗?我正在使用application.properties 连接到 JDBC,但似乎 Hikari CP 在设置此属性之前已连接。有问题吗?
  • 在整个 JVM 的第一个 DNS 解析之前设置属性很重要。在配置 Hikari CP 的位置设置它应该可以工作,但需要对其进行测试,因为在调用此类之前可能会解析另一个名称。
【解决方案3】:

从here 看来您应该设置sun.net.inetaddr.ttl。这对我有用。

链接示例:

java -Dsun.net.inetaddr.ttl=1 test
Enter the hostname
rrr
Output isrrr/129.145.146.100
Enter the hostname
rrr
Output isrrr/129.147.146.100

【讨论】:

猜你喜欢
  • 2011-11-04
  • 1970-01-01
  • 2015-05-16
  • 2012-06-14
  • 2021-11-26
  • 2020-08-22
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多