java让host的修改立即生效

结论在文章结尾,我们先看过程

示例程序:

public static void main(String[] args) throws Exception {

        for (int i = 0; i < 100; i++) {
            InetAddress addresses = InetAddress.getByName("www.baidu.com");
            System.out.println(addresses.getHostAddress());
            System.out.println(addresses.getHostName());
            Thread.sleep(1000);
        }

    }

本地添加一条host:127.0.0.1 www.baidu.com

发现并没立即生效,大概30s之后生效的。
看了下源码,是从InetAddressHolder去拿的,以为这里做了文章。


image.png

但是发现InetAddress和InetAddressHolder都是一起改的,并没有什么因果关系


image.png

那重点就回到有的时候不改,不改的时候走的逻辑就是我们关注的地方了。


image.png

看到是用了cache的。那么cache什么情况下失效呢?


image.png

可以看到CacheEntry是有个expiration过期时间字段的。


image.png

过期时间是在哪里设置的呢?我们直接用这个字段来断点


image.png

看到是默认缓存30s,是在put进缓存的时候设置的。
这个30s是在哪里设置的呢,看到是InetAddressCachePolicy的cachePolicy字段来决定的。debug这个字段,看看是哪里修改的


image.png

可以看到默认是30s。

所以如果要禁止缓存的话,可以

1. 设置java.security.Security.setProperty("networkaddress.cache.ttl", "0");
2 jvm启动参数中设置-Dsun.net.inetaddr.ttl=0

当然我们也可以通过反射的方式,强行清空缓存:

public static void clearCache() throws NoSuchFieldException, IllegalAccessException {
        Field field = java.net.InetAddress.class.getDeclaredField("addressCache");
        field.setAccessible(true);
        Object addressCache = field.get(null);

        Field cacheMapField = addressCache.getClass().getDeclaredField("cache");
        cacheMapField.setAccessible(true);
        Map cacheMap = (Map) cacheMapField.get(addressCache);
        cacheMap.clear();
    }

你可能感兴趣的:(java让host的修改立即生效)