如何使Java遵守DNS缓存超时?

2022-08-31 09:26:03

我们使用GSLB进行地理分布和负载平衡。每个服务都分配有一个固定的域名。通过一些DNS魔术,域名被解析为最接近服务器的IP,负载最小。要使负载平衡正常工作,应用程序服务器需要遵守来自 DNS 响应的 TTL,并在缓存超时时再次解析域名。但是,我无法找到在Java中执行此操作的方法。

该应用程序采用Java 5,在Linux(Centos 5)上运行。


答案 1

根据 Byron 的答案,您不能通过使用标志或调用来设置或作为系统属性,因为这些不是系统属性 - 它们是安全属性。networkaddress.cache.ttlnetworkaddress.cache.negative.ttl-DSystem.setProperty

如果要使用 System 属性来触发此行为(以便可以使用标志或调用 ),则需要设置以下 System 属性:-DSystem.setProperty

-Dsun.net.inetaddr.ttl=0

此系统属性将启用所需的效果。

但请注意:如果您在启动 JVM 进程时未使用该标志,而是选择从代码中调用它:-D

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

此代码必须在 JVM 中的任何其他代码尝试执行联网操作之前执行。

这很重要,因为,例如,如果您调用.war文件并将该.war部署到Tomcat,这将不起作用:Tomcat使用Java网络堆栈来初始化自身的时间远远早于.war代码的执行。由于这种“争用条件”,在启动JVM进程时使用标志通常更方便。Security.setProperty-D

如果不使用或调用 ,则需要在该文件中编辑和设置这些安全属性,例如-Dsun.net.inetaddr.ttl=0Security.setProperty$JRE_HOME/lib/security/java.security

networkaddress.cache.ttl = 0
networkaddress.cache.negative.ttl = 0

但请注意围绕这些属性的注释中的安全警告。仅当您有理由确信自己不容易受到 DNS 欺骗攻击时,才执行此操作。


答案 2

Java有一些非常奇怪的dns缓存行为。您最好的办法是关闭dns缓存或将其设置为某个低数字,例如5秒。

networkaddress.cache.ttl(默认值:-1)
指示从名称服务成功查找名称的缓存策略。该值指定为整数,以指示缓存成功查找的秒数。值 -1 表示“永久缓存”。

networkaddress.cache.negative.ttl(默认值:10)
指示从名称服务中查找名称不成功的缓存策略。该值指定为整数,以指示缓存失败的不成功查找的秒数。值为 0 表示“从不缓存”。值 -1 表示“永久缓存”。


推荐