Java: JVM DNS cache settings

2 min read | by Jordi Prats

One of the annoyances of running workloads in a JVM is taking into account that it has it's own DNS cache: It's easy to forgot about it when troubleshooting an issue so we might end up not understanding the problem at all

When a hostname had been resolved earlier and stored in the cache it helps reducing the latency but we might have several layers for caching the same DNS query that might cause problems:

  • We might have a name resolver (with it's own caching)
  • A cache on the system itself
  • JVM itself

There are even some JVM setttings to control how long cached entries are valid and a negative cache as well which stores unsuccessful lookup so that no time is spent on doing that again:

  • networkaddress.cache.ttl
  • networkaddress.cache.negative.ttl

Fun comes when there are several settings that controls just the same cache, and depending on the JVM you are running they might behave in a different way:

  • sun.net.inetaddr.ttl
  • sun.net.inetaddr.negative.ttl

We can test it using the following java code:

import java.net.*; 
import java.io.*; 
import java.util.*; 
import java.net.InetAddress; 
import java.security.Security;
import java.util.concurrent.TimeUnit;

public class addr 
{ 
    public static void main(String args[]) throws Exception 
    {
      System.out.println(Security.getProperty("networkaddress.cache.ttl"));
        System.out.println(System.getProperty("sun.net.inetaddr.ttl"));
        while(true)
        {
            InetAddress localhost = InetAddress.getByName("pet2cattle.com"); 
            System.out.println("IP Address : " + 
                        (localhost.getHostAddress()).trim());
            TimeUnit.SECONDS.sleep(10);
        }
    } 
} 

If we set the ttl cache to -1 it means it will keep the record for as long as the JVM runs, setting sun.net.inetaddr.ttl to zero (no cache) and networkaddress.cache.ttl to -1 (infinite cache) allows us to check for a DNS record which setting takes preference. Obviously we need to do it on a DNS record that we can change:

# java -version
openjdk version "14.0.2" 2020-07-14
OpenJDK Runtime Environment (build 14.0.2+12-Ubuntu-120.04)
OpenJDK 64-Bit Server VM (build 14.0.2+12-Ubuntu-120.04, mixed mode, sharing)
# java -Dnetworkaddress.cache.ttl=-1 -Dsun.net.inetaddr.ttl=0 addr
-1
0
IP Address : 4.4.4.4
IP Address : 4.4.4.4
IP Address : 4.4.4.4
(...)

So we can conclude from this experiment that, at least with openjdk 14.0.2, networkaddress.cache.ttl takes preference over sun.net.inetaddr.ttl.


Posted on 11/05/2022

Categories