JAVADNS缓存原理
日常上网大家一般都是使用域名,比如www.baidu.com。当你在浏览器输入了www.baidu.com的时候,就是用到了DNS技术。将域名解析为ip地址。
域名是分等级的,分为:根域名、顶级域名、次级域名、主机名。一般格式如下:主机名.次级域名.顶级域名.根域名。
二、JAVA中使用DNS
有两种方式:
使用InetAddress的getByName方法
InetAddress inetAddress = InetAddress.getByName("unKnownHost");
Socket ss = newSocket(inetAddress,123);
直接使用Socket封装好的(不推荐):
Sockets = newSocket("unKnownHost",123);
三、JAVA对DNS的缓存
java获取host对应ip的过程如下(只关注查找ip的过程):
1.通过host先去本地缓存中获取,本地缓存分为addressCache(有效缓存)和negativeCache(无效缓存)
1.1如果addressCache中存在,则返回缓存的结果
1.2如果negativeCache中存在,则返回unknown_array,外层会抛出UnKnownHostException
1.3如果两个缓存均不存在,则返回null
2.如果缓存返回的为null,则去nameService中去查询。这里有一个小优化,jdk维护了一个lookupTable对象,存放正在查询的域名。
2.1 如果lookupTable中存在host,则说明有另外一个线程在查询,当前线程等待另外一个线程完成。
2.2 如果lookupTable中不存在host,则将该host放入lookupTable中,并去nameService中查询,查询nameService后,无论结果,均会唤醒所有在等待的线程。
2.3这样做的好处,防止同样的host并发去查询dns,这也是一种防止缓存雪崩的技术。
四、缓存策略
那么有读者就要问了,因为ip有可能改变,那么缓存的时间是怎么控制的。那就看另外一个类:InetAddressCachePolicy
有四个参数可以控制缓存时间(-1 永久有效;0 不缓存;其余正值 缓存时间):
networkaddress.cache.ttl 有效缓存时间(优先级高)
sun.net.inetaddr.ttl 有效缓存时间(优先级低)
networkaddress.cache.negative.ttl 无效缓存时间(优先级高)
sun.net.inetaddr.negative.ttl 无效缓存时间(优先级低)
这四个参数,均可以通过启动java程序中,增加-D参数进行传入
五、坑
还记得前边说的不建议直接使用socket的String类型host构造函数吗?我认为哪个是坑。代码中可以看到,异常被吞掉了,虽然对外的结果都是UnknownHostException,但是缺少了第一手的堆栈信息,很难区分是由于缓存的无效地址还是因为查找失败。
以上是 JAVADNS缓存原理 的全部内容, 来源链接: utcz.com/z/517987.html