How to configure DNS caching timeout in a Spring Boot docker image?

art_ptushkin

Artem Ptushkin

Posted on March 26, 2024

How to configure DNS caching timeout in a Spring Boot docker image?

JVM build used for this article eclipse-temurin:21-jdk:

openjdk 21.0.2 2024-01-16 LTS
OpenJDK Runtime Environment Temurin-21.0.2+13 (build 21.0.2+13-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.2+13 (build 21.0.2+13-LTS, mixed mode, sharing)
Enter fullscreen mode Exit fullscreen mode

We must differentiate JVM Security properties and System properties.

  • Security properties:
    • can not be affected directly by the command line
    • accessed with class java.security.Security
    • can be modified through the file -Djava.security.properties=/java-additional.security
  • System properties
    • can be affected directly by the command line
    • accessed with class java.lang.System

Important to know:

  • Default value of the property is 30 (seconds) and can be found in sun.net.InetAddressCachePolicy#DEFAULT_POSITIVE

  • This class reads the property once during the class initialization in the static method - this is important for further conclusions

  • How to debug: open java.net.InetAddress line ~1141 cachePolicy = InetAddressCachePolicy.get(); and call the code InetAddressCachePolicy.get() through the debug execution

Initial options to set the value:

  • Security property networkaddress.cache.ttl (through the file)
  • System property sun.net.inetaddr.ttl (through JVM command line)

Technical in JVM it's possible to set a value in runtime (e.g. System.setProperty or Security.setProperty but this is misleading here's why:

You don't know when a property will be accessed by any code. You must either determine that you set it before other code accesses it or there is a risk that it will be not applied.

Therefore, to mediate the risk and the checks we should set the value as JVM startup parameters (not runtime).

Let's consider 3 typical build setups:

  • fat jar
  • Spring Boot docker build
  • Goole jib

Fat jar

There are plenty of options on how to set a JVM property, one example

Security properties with Gradle example

# gradle.properties
org.gradle.org.gradle.jvmargs="-Djava.security.properties=/your/path/java-additional.security"
Enter fullscreen mode Exit fullscreen mode

Security properties with Googe Jib plugin

# build.gradle.kts
jib {
    extraDirectories {
        paths {
            path {
                setFrom("java-additional.security")
                into = "/etc/java-additional.security"
            }
        }
    }
    container {
        jvmFlags = listOf("-Djava.security.properties=/etc/java-additional.security/java.security")
    }
    from {
        image = "eclipse-temurin:21-jre"
    }
}
Enter fullscreen mode Exit fullscreen mode

You can reproduce the same code with other build tools and with the Dockerfile too.

Event this is not enough

Spring uses Apache HTTP client underneath and by default connection TTL there is infinite. You can change it to (see):

@Bean
    fun poolingHttpClientConnectionManager(): PoolingHttpClientConnectionManager =
        PoolingHttpClientConnectionManagerBuilder
            .create()
            .apply {

                setDefaultConnectionConfig(ConnectionConfig
                    .custom()
                    .setTimeToLive(TimeValue.ofMinutes(30))
                    .build()
                )
            }
            .build()

// which you set to 

HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager)
Enter fullscreen mode Exit fullscreen mode

Links

💖 💪 🙅 🚩
art_ptushkin
Artem Ptushkin

Posted on March 26, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related