Java有个叫DNS Caching in Java Virtual Machines. 它不像其他大部分的Stand-alone的桌面应用和网络应用一样,直接将系统的DNS Flush一下或重启就可以生效。Jdk为了提升系统性能,通过InetAddress将网络访问后的dns解析结果cache起来,并提供了以下方法来查询hostname和IP的匹配关系。
除了InetAddress可以查询缓存的信息, Java中用了四个属性来管理JVM DNS Cache TTL(Time To Live),即DNS Cache的缓存失效时间。(这才有点像是要说到重点了~)
networkaddress.cache.ttl
- 缓存正确解析后的IP地址
- 指定的整数表明会缓存正确解析的DNS多长时间
- 默认值为-1, 代表在JVM启动期间会一直缓存
- 如果设置为0,则表示不缓存正确解析的结果
- 如果不设置,默认缓存30秒
networkaddress.cache.negative.ttl
- 缓存解析失败结果,可以减少DNS服务器压力
- 指定的整数表明会缓存解析失败结果多长时间
- 默认值为10,表示JVM会cache失败解析结果10秒
- 如果该值设置为0, 则表示不缓存失败结果
sun.net.inetaddr.ttl
- 私有变量,对应networkaddress.cache.ttl
- 这个参数,只能在命令行中被设置值。
sun.net.inetaddr.negative.ttl
- 私有变量,对应networkaddress.cache.negative.ttl,
- 同样,只能在命令行中被设置值。
使用DNS Caching in Java Virtual Machines文中提到的方式,我们可以通过以下三种方式来进行对host修改后的实时生效:
- 编辑$JAVA_HOME/jre/lib/secerity/java.security文件中将网络地址缓存属性(networkaddress.cache.ttl和networkaddress.cache.negative.ttl)的值修改为你想要的值;优点是一劳永逸性的修改,非编程式的解决方案; 但java.security是公用资源文件,这个方式会影响这台机器上所有的JVM
- 在代码中可直接将动态配置,方式如下:
java.security.Security.setProperty(“propertyname”, “value”)
好处是,只影响当前的JVM,不影响他人,但缺点是,它是编程式的,
但正是利用了这一点,让我们的host文件修改可以实时生效
举个例子:
- 在JVM启动时,在命令行中加入-Dsun.net.inetaddr.ttl=value and -Dsun.net.inetaddr.negative.ttl=value这两个指令,也可以起到配置缓存DNS失效时间作用。但注意这个方式,只在当networkaddress.cache.*属性没有配置时才能起作用。