JVM DNS 缓存配置

域名解析并非一个简单的过程,其解析结果可能会被层层缓存,如浏览器 DNS 缓存、操作系统 DNS 缓存、ISP 的 DNS缓存,容易被忽略的是 JVM 本身也会对 DNS 进行缓存。

JVM 的 DNS 缓存可以通过以下参数进行配置:

  • networkaddress.cache.ttl
  • sun.net.inetaddr.ttl
  1. 如果开启了 SecurityManager,优先从 ${java.home}/jre/lib/security/java.security 中读取参数 networkaddress.cache.ttl,单位为秒。
  2. 如果未读取到,则会读取启动参数 sun.net.inetaddr.ttl 作为缓存 ttl.
  3. 如果以上参数均未读取到,并且未开启 SecurityManager,则会使用默认值 30s.
  4. 否则使用初始值 -1,表示永久生效。

以上逻辑可以在 InetAddressCachePolicy.class 中体现,反编译后,有如下代码

static {
        Integer var0 = (Integer)AccessController.doPrivileged(new PrivilegedAction<Integer>() {
            public Integer run() {
                String var1;
                
                // 优先读取 networkaddress.cache.ttl
                try {
                    var1 = Security.getProperty("networkaddress.cache.ttl");
                    if (var1 != null) {
                        return Integer.valueOf(var1);
                    }
                } catch (NumberFormatException var3) {
                    ;
                }
                    
               // 未读取到,则读取启动参数 sun.net.inetaddr.ttl
                try {
                    var1 = System.getProperty("sun.net.inetaddr.ttl");
                    if (var1 != null) {
                        return Integer.decode(var1);
                    }
                } catch (NumberFormatException var2) {
                    ;
                }

                return null;
            }
        });
        if (var0 != null) {
            cachePolicy = var0.intValue();
            if (cachePolicy < 0) {
                cachePolicy = -1;
            }

            propertySet = true;
        } else if (System.getSecurityManager() == null) {
            // 如果未启用 SecurityManager,使用默认值 30
            cachePolicy = 30;
        }

其中 cachePolicy 初始值为 -1,表示缓存永不失效。

我们通过以下代码对 DNS 缓存参数进行测试:

public class HostProcessor implements Runnable {

    private int count = 1;

    /**
     * 每秒解析1次 www.baidu.com 的 IP
     */
    @Override
    public void run() {
        while (true) {
            System.out.println(count);
            printIp("www.baidu.com");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            count = count + 1;
            System.out.print("\r\n");
        }
    }

    /**
     * 解析并打印 IP
     */
    private void printIp(String host) {
        InetAddress address = null;
        try {
            address = Inet4Address.getByName(host);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        if (address == null) {
            return;
        }

        System.out.println(address.getHostAddress());
        System.out.println(address.getHostName());
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new HostProcessor());
        thread.start();
    }
}

networkaddress.cache.ttl 参数测试
首先修改 java.security 中的 networkaddress.cache.ttl 配置,改为以下值:

networkaddress.cache.ttl=15

启动程序,开始打印域名对应 IP 后,立刻修改 /etc/hosts,将 www.baidu.com 指向到陌生 IP:

47.95.164.112   www.baidu.com

观察控制台输出,有如下结果:

在 15 秒后,对 host 映射的修改才反应出来

sun.net.inetaddr.ttl 参数测试
注释掉 java.security 中的 networkaddress.cache.ttl 配置,如下:

#networkaddress.cache.ttl=15

添加程序启动参数:

-Dsun.net.inetaddr.ttl=10

同样启动程序后,将原先 host 文件的修改回退,观察到如下输出:

在 10 秒后,对 host 映射的修改才反应出来

除了解析成功的结果,JVM 也会缓存解析失败的结果,可以通过下列参数配置:

  • networkaddress.cache.negative.ttl
  • sun.net.inetaddr.negative.ttl
    这里不展开介绍
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EricZH1025

创作不易,欢迎打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值