博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android DNS cache
阅读量:3522 次
发布时间:2019-05-20

本文共 2047 字,大约阅读时间需要 6 分钟。

当服务端IP变化,大量用户还是访问的以前的IP,连接不上服务器。

我们的客户端软件如何通过域名正确访问服务器?这里面主要涉及到DNS缓存的问题。

什么是DNS?

DNS 是 (Domain Name System) 的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个,能够使人更方便的访问,而不用去记住能够被机器直接读取的IP数串。简单说,DNS就是 域名(我们平时使用的网址,如www.sina.com.cn等)到 ip 地址的 服务器。

因为计算机访问对方服务器时,只能识别对方服务器的ip地址,所以当我们输入网址时,就需要先到DNS服务器查询对应的IP地址,然后再访问。

DNS缓存

DNS访问是个比较耗时的操作,所以android会把查询到的结果缓存起来,下次查询的时候,就可以直接从缓存中获取,而不需要DNS查询。

DNS解析缓存分为两种:查询成功的缓存,查询失败的缓存(如查询域名不存在等) 。

android 系统对DNS缓存 有两个地方,一个是虚拟机层 , 一个是 框架层 java.net.InetAddress 类内部维护了一个缓存。

当通过域名解析IP地址时,通过 java.net.InetAddress类来调用相应的方法。它会先查看自身缓存里有没有,木有的话会看虚拟机层有木有缓存还木有的话才会到DNS服务器查询。

控制DNS缓存

有些情况下,我们不能使用DNS缓存,如服务器IP地址变化等。

虚拟机层默认使用的缓存策略是 成功的查询永久缓存(这里的永久缓存是指整个虚拟机生命周期,虚拟机重启,缓存就没有了) , 失败的查询只缓存10s

我们可以设置虚拟机的DNS缓存时间TTL (time-to-live 生命周期):

[java] 
  1. Security.setProperty("networkaddress.cache.ttl", String.valueOf(0));  
  2. Security.setProperty("networkaddress.cache.negative.ttl", String.valueOf(0));  
"networkaddress.cache.ttl"表示查询成功的缓存,"networkaddress.cache.negative.ttl"表示查询失败的缓存。第二个参数表示缓存有效时间,单位是秒。

时间 -1 表示永久缓存,0 表示从不缓存,其他表示缓存具体有效时间。

java.net.InetAddress内部的缓存我们没有办法控制。4.0以前是永久缓存,4.0以后是只缓存2s。也就是说4.0以前通过设置虚拟机TTL没有用,因为java.net.InetAddress永久缓存了。

下面是android api InetAddress 里的原话:

DNS caching

In Android 4.0 (Ice Cream Sandwich) and earlier, DNS caching was performed both by InetAddress and by the C library, which meant that DNS TTLs could not be honored correctly.In later releases, caching is done solely by the C library and DNS TTLs are honored.

在控制DNS缓存时有两点需要注意:

    1. 可以根据实际情况来设置networkaddress.cache.ttl属性的值。一般将这个属性的值设为-1.但如果访问的是动态映射的域名(如使用动态域名服务将域名映射成ADSL的动态IP), 就可能产生IP地址变化后,客户端得到的还是原来的IP地址的情况。

    2. 在设置networkaddress.cache.negative.ttl属性值时最好不要将它设为-1,否则如果一个域名因为暂时的故障而无法访问,那么程序再次访问这个域名时,即使这个域名恢复正常,程序也无法再访问这个域名了。除非重新运行程序。

IP变化解决方案

当服务端IP变化,我们的软件又必须通过域名正确访问服务器。

最简单且通用的解决办法是,重启应用程序。

但是我们没有办法控制用户的行为,用户要是不停止程序的话,就永远连不上。

解决方案1:在 Application 的 onCreate()里设置虚拟机不缓存DNS。

假设用户此时正在使用我们的软件,此时域名改变IP指向,用户断线重连后会获得正确的IP,成功连接。InetAddress 缓存的那2s可以不考虑了。

缺点:4.0下不管用。

解决方案2:在第一次域名解析成功后,将IP地址存到文件里。下次连接的时候优先使用保存的IP地址,只有当IP地址连接不上时,才进行域名解析,解析成功后,再次保存IP。

方案一加方案二一起解决了大多数用户的问题。

转载地址:http://zeqqj.baihongyu.com/

你可能感兴趣的文章
String与StringBuilder与StringBuffer三者的差别
查看>>
各种IO流之间的关系和区别
查看>>
SSM如何实现上传单图片
查看>>
SSM环境下java如何实现语音识别(百度语音识别版)
查看>>
ajax方法参数的用法和他的含义
查看>>
数据库基础技巧及用法
查看>>
实用方法:无request参数时获得当前的request的方法
查看>>
JS操作数组常用实用方法
查看>>
java实现MD5多次进行加密加盐操作
查看>>
springboot实现CAS的server服务器端的搭建,并实现链接mysql数据库,自定义加密算法
查看>>
Python超详细的安装教程
查看>>
小甲鱼Python第一讲(我和Python的第一次亲密接触)
查看>>
小甲鱼Python第三讲(小插曲之变量和字符串)
查看>>
小甲鱼Python第十一讲(一个打了激素的数组2)
查看>>
小甲鱼Python第十三讲(戴上了枷锁的列表)
查看>>
小甲鱼Python第十四讲(各种奇葩的内置方法)
查看>>
小甲鱼Python第十五讲(格式化)
查看>>
小甲鱼Python第十七讲(Python的乐高积木)
查看>>
小甲鱼Python第十八讲(函数:灵活即强大)
查看>>
小甲鱼Python第十九讲(函数,我的地盘听我的)
查看>>