Dns&HttpDns

113 阅读5分钟

##目录 1、Dns 2、HttpDns

##1、Dns dns流程

  1. 终端向LocalDNS发起递归查询。

  2. LocalDNS(未开启转发模式),则向根DNS服务器发起迭代查询请求。(如开启转发模式,则转发至上级localDns)

(任何LocalDNS都需知道根DNS服务器的IP地址(全球共13台)。)

  1. 根DNS服务器返回一级域名服务器IP地址,(com DNS服务器的IP地址)。

(LocalDNS将com DNS服务器及其IP地址加入到缓存,下次DNS请求,在缓存未过期的情况下,授权给com 区的域名需向com DNS服务器请求查询时,直接往com DNS服务器发查询请求,不再向根DNS服务器请求。)

  1. LocalDNS服务器向一级域名服务器(com DNS服务器)发起迭代查询请求。

  2. com DNS服务器返回二级域名服务器IP地址(wangsu.com DNS服务器的IP地址)。

(LocalDNS将wangsu.comDNS服务器及其IP地址加入到缓存,下次DNS请求,在缓存未过期的情况下,授权给wangsu.com区的域名需向wangsu.com DNS服务器请求查询时,直接往对应 DNS服务器发查询请求,不再向根DNS服务器及com DNS服务器请求。)

  1. LocalDNS服务器向wangsu.com DNS服务器发起迭代查询请求。

7.wangsu.com DNS服务器给出域名的IP地址。

(LocalDNS将www.wangsu.com  IP地址加入到缓存,下次相同的DNS请求,在缓存未过期的情况下,LocalDNS直接给出该域名的IP地址,不再向权威DNS服务器查询。)

  1. LocalDNS服务器将该域名对应的IP地址返回给终端用户,

(DNS客户端将域名对应的IP地址接入缓存。下次请求该域名时,若缓存未过期,DNS客户端直接从缓存取出IP,不再向LocalDNS发起迭代查询。)

递归查询指如果终端用户所请求的LocalDNS服务器不知道被查询的域名的IP地址,则以DNS客户端的身份,向其它域名服务器继续发出查询请求报文(即替主机继续查询),而不是让主机自己进行下一步查询。因此,递归查询返回的查询结果或者是所要查询的IP地址,或者是报错,表示无法查询到所需的IP地址。

迭代查询指域名服务器或者给出最终结果,或者告诉DNS客户(此处指LocalDNS)应去哪些DNS服务器查询。

递归查询LocalDNS如果没有记录客户端发过来的域名对应的ip地址,则以客户端的身份,根域名服务器发起迭代查询,迭代查询是值,根域名服务器不直接告诉LocalDNS结果,而是告诉LocalDNS去哪里查询,然后LocalDNS一级一级的查询,直至最终得到结果。

##2、httpdns

###2.1、httpdns解决的问题

####2.1.1、域名劫持 1、黑客侵入了宽带路由器并对Local DNS进行篡改; 2、攻击者还可以监听终端用户的域名解析请求,并在Local DNS返回正确结果之前将伪造的DNS解析响应传递给终端用户 3、Local DNS针对部分域名的缓存进行更改

####2.1.2、调度不精准

由于运营商策略的多样性,其 Local DNS 的解析结果可能不是最近、最优的节点。

部分Local DNS A供应商为了降低运营成本,会将请求到自己节点的域名解析请求转发给其他供应商的Local DNS B节点,Local DNS B请求权威dns解析时,权威dns会根据Local DNS B的ip,分配离Local DNS B地理位置最近的ip地址。

Local DNS的布点受成本因素制约分布并不均匀也会导致上述调度不准的问题。

###2.2、HTTPDNS 1、使用HTTP协议进行域名解析,将域名解析请求直接发送到HTTPDNS服务端,绕过运营商 Local DNS ,避免域名劫持。 2、HTTPDNS服务端会将终端用户的IP信息直接交付给权威DNS,从而解决调度不精准的问题。 3、另外通过域名预解析、缓存(DNS解析结果)、(解析结果)懒更新策略等方式实现无延迟解析。

#####2.2.1、预加载 app启动时,可以对我们后续需要用到的域名,调用HTTPDNS SDK中的预解析方法发起异步的预解析请求。

域名预解析

#####2.2.2、懒更新

所谓懒加载策略,核心的实现思路如下:

1、如果缓存中没有记录,那么异步网络请求HTTPDNS解析,获取解析结果。 (网络请求需要异步,同步调用需要直接拿到结果,可采取线程池+Future的策略) 2、如果缓存中存在记录,不论过期与否,直接返回业务层缓存中的记录; 3、如果缓存中的记录已过期,后台发起异步网络请求进行HTTPDNS解析;

绝大多数场景下域名对应IP变更并不频繁,特别是在单次APP的使用周期内,域名解析出的IP往往是相同的。 另一方面,即使域名对应的IP发生改变,后台会异步发起的异步HTTPDNS解析解析会很快获取最新解析结果 ,结合我们的网络重试策略,保证了下一次网络请求的正确性。

懒更新

#####2.2.3、OKhttp+HttpDns

public class OkHttpDns implements Dns {
    private static final Dns SYSTEM = Dns.SYSTEM;
    HttpDnsService httpdns;//httpdns 解析服务
    private static OkHttpDns instance = null;
    private OkHttpDns(Context context) {
        this.httpdns = HttpDns.getService(context, "account id");
    }
    public static OkHttpDns getInstance(Context context) {
        if(instance == null) {
            instance = new OkHttpDns(context);
        }
        return instance;
    }
    @Override
    public List<InetAddress> lookup(String hostname) throws UnknownHostException {
        //通过异步解析接口获取ip
        String ip = httpdnsManager.getIpByHost(hostname);
        if(ip != null) {
            //如果ip不为null,直接使用该ip进行网络请求
            List<InetAddress> inetAddresses = Arrays.asList(InetAddress.getAllByName(ip));
            Log.e("OkHttpDns", "inetAddresses:" + inetAddresses);
            return inetAddresses;
        }
        //如果返回null,走系统DNS服务解析域名
        return Dns.SYSTEM.lookup(hostname);
    }
}

//给okhttpclient设置自定义的dns
private void okhttpDnsRequest() {
    OkHttpClient client = new OkHttpClient.Builder()
    .dns(OkHttpDns.getInstance(getApplicationContext()))
    .build();

自定义一个类实现Dns,并重写Dns的lookup方法, 在这个方法中结合懒更新策略获取域名对应的ip,包装成InetAddress list进行返回。