编写了一个操作,可以自己将定义dns指向添加到jvm的dns查询缓存中,适用于不想将dns配置直接写入系统 /etc/hosts的情况。
/**
* 从hosts文件中读取dns配置,并加入本地jvm系统缓存中
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws IOException
* @throws InvocationTargetException
* @return 此次设置dns配置的数量
*/
public static int load() throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, IOException, InvocationTargetException {
List<Pair<String,String>> hosts=hosts();//读取项目中的host文件,获得项目中定义的dns配置
int totalLoaded=0;
if(hosts.size()>0){
//获取jvm的dns缓存设置方法
Field f =InetAddress.class.getDeclaredField("addressCache");
f.setAccessible(true);
Object addressCache=f.get(null);
Method put=addressCache.getClass().getDeclaredMethod("put",String.class,InetAddress[].class);
put.setAccessible(true);
//获取原先的缓存策略
int policy=InetAddressCachePolicy.get();
//将本地dns设置的缓存策略设置为永远有效
Field cachePolicy=InetAddressCachePolicy.class.getDeclaredField("cachePolicy");
cachePolicy.setAccessible(true);
cachePolicy.set(null,InetAddressCachePolicy.FOREVER);
//解析host配置,加载入jvm缓存
for(Pair<String,String> host : hosts){
String ip=host.getValue();
String[] hostNames=host.getKey().split(",");
for(String hostName :hostNames){
if(hostName.length()==0) continue;
put.invoke(addressCache,hostName,new InetAddress[]{InetAddress.getByAddress(hostName,address(ip))});
totalLoaded++;
log.debug("load InetAddress set "+ip+" "+hostName);
}
}
//将缓存策略替换为原先的默认值
cachePolicy.set(null,policy);
}
return totalLoaded;
}
/**
* 将字符串形式的ip地址转换成字节形式
* @param ip
* @return
*/
private static byte[] address(String ip){
boolean isIp=true;
for(char c : ip.toCharArray()){
if((c>'9'||c<'0')&&c!='.'){
isIp=false;
break;
}
}
if(!isIp) return null;
String[] ipArr=ip.split("\\.");
byte[] bip=new byte[ipArr.length];
for(int i=0;i<ipArr.length;++i){
bip[i]=(byte)(Integer.parseInt(ipArr[i],10)&0xff);
}
return bip;
}