How to make Java honor the DNS Caching Timeout?
We use GSLB for geo-distribution and load-balancing. Each service is assigned a fixed domain name. Through some DNS magic, the domain name is resolved into an IP that's closest to the server with least load. For the load-balancing to work, the application server needs to honor the TTL from DNS response and to resolve the domain name again when cache times out. However, I couldn't figure out a way to do this in Java.
The application is in Java 5, running on Linux (Centos 5).
Solution 1:
Per Byron's answer, you can't set networkaddress.cache.ttl
or networkaddress.cache.negative.ttl
as System Properties by using the -D
flag or calling System.setProperty
because these are not System properties - they are Security properties.
If you want to use a System property to trigger this behavior (so you can use the -D
flag or call System.setProperty
), you will want to set the following System property:
-Dsun.net.inetaddr.ttl=0
This system property will enable the desired effect.
But be aware: if you don't use the -D
flag when starting the JVM process and elect to call this from code instead:
java.security.Security.setProperty("networkaddress.cache.ttl" , "0")
This code must execute before any other code in the JVM attempts to perform networking operations.
This is important because, for example, if you called Security.setProperty
in a .war file and deployed that .war to Tomcat, this wouldn't work: Tomcat uses the Java networking stack to initialize itself much earlier than your .war's code is executed. Because of this 'race condition', it is usually more convenient to use the -D
flag when starting the JVM process.
If you don't use -Dsun.net.inetaddr.ttl=0
or call Security.setProperty
, you will need to edit $JRE_HOME/lib/security/java.security
and set those security properties in that file, e.g.
networkaddress.cache.ttl = 0
networkaddress.cache.negative.ttl = 0
But pay attention to the security warnings in the comments surrounding those properties. Only do this if you are reasonably confident that you are not susceptible to DNS spoofing attacks.
Solution 2:
Java has some seriously weird dns caching behavior. Your best bet is to turn off dns caching or set it to some low number like 5 seconds.
networkaddress.cache.ttl (default: -1)
Indicates the caching policy for successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the successful lookup. A value of -1 indicates "cache forever".networkaddress.cache.negative.ttl (default: 10)
Indicates the caching policy for un-successful name lookups from the name service. The value is specified as as integer to indicate the number of seconds to cache the failure for un-successful lookups. A value of 0 indicates "never cache". A value of -1 indicates "cache forever".
- http://java.sun.com/j2se/1.4.2/docs/api/java/net/InetAddress.html