Android DNS更新与DNS-Prefetch

一、什么是DNS

DNS(Domain Name System,域名系统),dns用于将域名解析解析为ip地址。

例如:给你www.baidu.com的主机名,你给 
我查出对应的ip地址:163.177.151.109。一些主机名还会有别名,如www.baidu.com就 
有别名www.a.shifen.com,甚至不止一个别名,或一个别名有2个ip地址。在linux机子 
上,运行nslookup(name service lookup)就是进行域名解析。如下面:

DNS工作方式分为递归查询和迭代查询,具体可参考下图

DNS还可以用于负载均衡、域名污染、防火墙,这些不在这里讨论。

二、DNS缓存

所谓DNS缓存有两种,比如主从同步缓存和本地缓存,这里对于手机来说,重点是本地DNS缓存。Android基于Linux系统,对于Android App来说,这个缓存又多了java层。

2.1 使用场景

当然,我们需要明白在Android App中那些场景需要进行,这才是最重要的,有时候其实并没有必要去更新缓存。总结一下,这里的场景无非如下几种:

场景一:存在多个运营商或者多个地区的分布式业务系统

比如互联网分布式业务系统,采取的是分区域、分运营商的方式不是业务系统。

场景二:存在多个域名的业务系统,需要提前解析并且缓存ip

这是taobao网的dns-prefetch link,这一步是为了加速其他页面的dns

场景三:ip地址唯一,但是存在多个子域名高并发请求

综上所述:我们可以理解为,当且仅当域名和ip地址的关系是“一对多”、“多对多”和“多对一”的情况下,可适当更新DNS缓存。

2.2系统版本情况说明

Android 4.3之前的TTL(Time To Live)分为正负两种有效期,正有效期为10分钟,最大缓存为120个,采用TTL算法回收。

Android 4.3+的系统,缓存修正为2秒,最大缓存为16个,采用LRU算法和TTL算法进行回收。

注意:以上代码参见java.net.AddressCache.java

三、Android DNS缓存更新

3.1、修正缓存过期时间

Android 4.3 之前,TTL可以用个System.setProperties进行设置,就可以将TTL修正为何Android 4.3+一致的生存时间

3.2 实现DNS-Prefetch

步骤3.1只是让缓存过期时间缩短了,一定程度上处理了 Android 4.3 之前系统的不足。但是,对于存在域名和ip“一对多”,“多对多”和“多对一”的分布式系统,如果出现网络切换,那么下次获“可能”取依旧比较耗时。因此,预获取dns是非常必要的。那么如何实现DNS-Prefetch呢

首先,我们需要统一规范接口

实现接口

使用时机

通常网络切换后,并且下次联网成功时,我们prefetch时最好的时间,这里我们需要通过Broadcast+IntentService

对于广播部分,我们需要监听如下两个Action(这里推荐使用动态广播)

广播实现代码

DnsUpdateIntentService 代码如下

注意:DnsUpdateIntentService 不可以注册为多进程,否则缓存无法更新

3.3、DNS防篡改与安全

Android 4.3之前的DNS可能存在被污染的可能,如修改resolv.conf文件,在Android 4.3+之后,统一使用Netd方式,安全性上有所提高。因此,对Android 4.3之前的系统,建议使用HttpDNS等方案,此外采取HTTPS的通信方式,一定程度上几乎可以绝对避免此类问题的发生。

此外,我们在ip与域名对应数量不大的app中,可以在App中提前建立不同机房的域名映射也是一种放置篡改的方案。

3.4、Android底层DNS更新

Android基于linux,底层通过Libcore.so更新DNS,目前没有方式来更新Linux层面的DNS缓存。那么,我们的DNS-Prefetch功能是否有必要呢?这个问题我们需要明确,虽然我们不一定能更新底层DNS,但是,可以促进底层DNS更新,类似System.gc()的作用。

参考链接


发布者

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注