Linux操做系統自己沒有對DNS緩存的支持(做爲客戶端時),若是爲了提高性能,可使用nscd提供DNS緩存的支持。php
java.net.InetAddress使用DNSNameService正向經過主機名得到IP地址,或者經過IP地址反向解析獲得主機名。 java.net.InetAddress提供了DNS解析成功的域名記錄的緩存,解析失敗的域名記錄的緩存。 解析成功的域名記錄的緩存的緩存有效期是永久的,解析失敗的域名記錄的緩存的有效期是10s。 這樣作的目的是提高性能,以及防止DNS欺騙攻擊。 當編程時,須要特別注意,一旦鏈接斷開,須要注意從新 new 一個 InetAddress 對象,並進行重連。html
清除InetAddress緩存的方法java
public static void clearCache() throws NoSuchFieldException, IllegalAccessException { //修改緩存數據開始 Class clazz = java.net.InetAddress.class; final Field cacheField = clazz.getDeclaredField("addressCache"); cacheField.setAccessible(true); final Object obj = cacheField.get(clazz); Class cacheClazz = obj.getClass(); final Field cachePolicyField = cacheClazz.getDeclaredField("type"); final Field cacheMapField = cacheClazz.getDeclaredField("cache"); cachePolicyField.setAccessible(true); cacheMapField.setAccessible(true); final Map cacheMap = (Map)cacheMapField.get(obj); System.out.println(cacheMap); cacheMap.remove("www.baidu.com"); //清除指定的域名緩存 }
JVM緩存了DNS的解析結果,一樣提供兩種記錄(解析成功和解析失敗)的緩存,可是相關的信息有JVM維護和管理。 不過sun提供了兩種方式對JVM的DNS成功和失敗緩存的有效期進行設置。編程
jre/lib/security/java.security 下的 networkaddress.cache.ttl 解析成功的緩存有效期,默認永久有效。bootstrap
jre/lib/security/java.security 下的 networkaddress.cache.negative.ttl 解析失敗的緩存有效期,默認10秒。瀏覽器
java.security.Security.setProperty("networkaddress.cache.ttl", "3"); java.security.Security.setProperty("networkaddress.cache.negative.ttl", "1");緩存
任意負值:緩存永久有效 0:不作緩存 正值:緩存多久(單位爲秒)
System.setProperty("sun.net.inetaddr.ttl", "3"); System.setProperty("sun.net.inetaddr.negative.ttl", "1");服務器
-Dsun.net.inetaddr.ttl=3 -Dsun.net.inetaddr.negative.ttl=1jvm
在Netty4.0版本以前是沒有對DNS的支持的,在4.0以後加入了DNS的。socket
可是在使用netty時,須要對使用域名進行鏈接的應用而言,須要特別注意對重連的考慮。 netty client使用InetSocketAddress指定服務端地址,而InetSocketAddress使用InetAddress進行域名的解析和緩存解析結果。這裏要特別消息,InetAddress使用DNSNameService進行解析的過程,受networkAddress.cache.ttl影響,可是解析後的結果InetSocketAddress,是不會再被刷新了,除非你本身去刷新。而且nio connect的時候使用的是InetSokcetAddress解析後的ip創建鏈接。
所以當使用域名的狀況下,當IP進行了切換致使鏈接斷開時,須要從新設置bootstrap的remoteAddress屬性,不然沒法進行IP的切換。