bigywater.tech
Java · 198

DNS 缓存:Java 如何缓存域名解析

Java 默认会把域名解析结果缓存多久?改了 networkaddress.cache.ttl 会怎样?失败的解析呢?这篇用独立的 JVM 在不同时刻重复解析同一个域名,把缓存的有效期实测出来(服务切换后迟迟不生效的问题经常源自这里)。

约 30 秒
默认的肯定缓存时间(t=29 s 仍命中、t=31 s 重新解析)
约 10 秒
失败解析(UnknownHostException)的默认缓存时间
70.58 → 0.485 ms
第一次解析 → 命中 JVM 缓存

默认缓存

实测 · 本机执行输出
  [默认(不设任何 networkaddress.cache 属性)]
    t=0s:70.580 ms | t=1s:0.485 ms | t=10s:0.139 ms | t=29s:0.293 ms | t=31s:1.698 ms
  [networkaddress.cache.ttl = 2]
    t=0s:58.160 ms | t=1s:0.338 ms | t=3s:1.823 ms
  [networkaddress.cache.ttl = 0(不缓存)]
    t=0s:56.956 ms | t=0.5s:3.294 ms | t=1s:3.523 ms
  [默认,一个不存在的域名(负缓存)]
    t=0s:115.210 ms | t=5s:0.345 ms | t=9s:0.227 ms | t=11s:4.079 ms
  [negative.ttl = 0(不缓存失败的解析)]
    t=0s:100.201 ms | t=1s:1.956 ms | t=2s:3.831 ms

调整 TTL 与负缓存

实测 · 本机执行输出
  networkaddress.cache.ttl = null(null 表示 java.security 里没有写,用 JVM 内置默认值);networkaddress.cache.negative.ttl = 10;sun.net.inetaddr.ttl 系统属性 = null

分步演示

DNS 缓存
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12,macOS,本机的真实 DNS(example.com 与一个不存在的 .invalid 域名)
    • 没有验证:Linux 上 libc 解析器与 /etc/hosts 的缓存差异、JDK 18+ 的自定义解析器 SPI(InetAddressResolverProvider)对缓存的影响、有 SecurityManager 时默认永久缓存的旧行为、HTTP 客户端各自的连接池与 DNS 的相互作用;耗时是单次测量
    京ICP备2026067502号-1京公网安备11010502063487号