OkHttp3应用[HTTP DNS的实现]

4. 例子

Fork me on Github,有更加的多交换可以与本人微信联系,在费城的开辟者能够与笔者面基。

The Application of HTTP DNS on OkHttp.

3. HTTP DNS的实现

在OkHttp中,提供了DNS的接口(这些接口基本没人知道,以至网上都未有座谈),方便客商本人达成lookup方法。下文实现了八个OkHttpClient单例,多个顶住dns,多少个顶住作业。

关于OkHttp,可以看此前的篇章

由此考查第三方DNS服务,看起来独有Tencent系的DNSPod依旧不错的,它向来回到三个ip地址,无需分析json等杂乱无章的事物,文书档案在这里。

DNSPod在重临的Header中,未有安装缓存,并积极断开了Socket连接,那样的话每一次进行lookup时都会开展三个GET央求,比较在此之前原生多了40ms。大家都精通DNS暗中认可的TTL时间一般是600s,由此大家能够通过复用OkHttp中的cache,在回来的response中参加Cache-Control的Header就足以兑现再第三次lookup时防止重复做客互联网。

static public synchronized OkHttpClient getHTTPDnsClient() {
  if (httpDnsclient == null) {
    final File cacheDir = GlobalContext.getInstance().getExternalCacheDir();
    httpDnsclient = new OkHttpClient.Builder()
        //消费者工作线程池
        .dispatcher(getDispatcher())
        //Logger拦截器     
        .addNetworkInterceptor(getLogger())
        .addNetworkInterceptor(new Interceptor() {
          @Override public Response intercept(Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            return originalResponse.newBuilder()
                //在返回header中加入缓存消息
                //下次将不再发送请求
                .header("Cache-Control", "max-age=600").build();
          }
        })
        //5MB的文件缓存
        .cache(new Cache(new File(cacheDir, "httpdns"), 5 * 1024 * 1024))
        .build();
  }
  return httpDnsclient;
}

max-age表示能够续600s;即使缓存命军长重临数据,反之抛出IOException。

通过测量检验,HTTP DNS工作意义如下:

  1. 在600s内,无论是或不是联网,都不会实行呼吁
  2. 在600s外,没联网时会抛出IOException,反之会进行HTTP哀告

随之,大家落实了DNS查询接口,值得注意的少数便是第三方服务器大概会挂,所以必然要细心有所极其并留出后路。

static Dns HTTP_DNS =  new Dns(){
  @Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
    //防御代码
    if (hostname == null) throw new UnknownHostException("hostname == null");
    //dnspod提供的dns服务
    HttpUrl httpUrl = new HttpUrl.Builder().scheme("http")
        .host("119.29.29.29")
        .addPathSegment("d")
        .addQueryParameter("dn", hostname)
        .build();
    Request dnsRequest = new Request.Builder().url(httpUrl).get().build();
    try {
      String s = getHTTPDnsClient().newCall(dnsRequest).execute().body().string();
      //避免服务器挂了却无法查询DNS
      if (!s.matches("\b(?:\d{1,3}\.){3}\d{1,3}\b")) {
        return Dns.SYSTEM.lookup(hostname);
      }
      return Arrays.asList(InetAddress.getAllByName(s));
    } catch (IOException e) {
      return Dns.SYSTEM.lookup(hostname);
    }
  }
};

在真正的事情乞求时,创设OkHttpClient时对DNS进行铺排就ok了

//真正的调用客户端,供Retrofit与Picasso使用
static public synchronized OkHttpClient getClient() {
  if (client == null) {
    final File cacheDir = GlobalContext.getInstance().getExternalCacheDir();
    client = new OkHttpClient.Builder().addNetworkInterceptor(getLogger())
        .cache(new Cache(new File(cacheDir, "okhttp"), 60 * 1024 * 1024))
        .dispatcher(getDispatcher())
        //配置DNS查询实现
        .dns(HTTP_DNS)
        .build();
  }
  return client;
}

1. HTTP DNS 的介绍

HTTP DNS通过将域名询问需要放入http中的一种域名深入分析方法,而不用系统自带的libc库去查询运转商的DNS服务器,有越来越大的自由度。近来微信,qq邮箱、等事务均运用了HTTP DNS,详见这里

第一优点

  • 可见正确地将站点剖析到离客商方今的CDN站点,方便进行流量调整
  • 缓和一部分营业商DNS不可能分析外国站点的难点
  • TCP在放任自流程度足防止止UDP无校验导致的DNS诈骗(举例墙,运行商广告,404导航站),当然基于HTTP的话本质照旧葡亰导航站,不安全的。

2.2. HTTP DNS流程

//拼装HTTP请求(OkHttp)
client.newCall
//JDK层,进行socket请求
Socket.connect(socket.java)
//framework层
libcore.io.IoBridge.connect
//进行tcp连接(JNI/C)
....

2.1. Android下native DNS查询过程

//JDK层调用
InetAddress.lookupHostByName()(InetAddress.java);
Libcore.os.android_getaddrinfo(InetAddress.java)
//framework下调用
libcore.io.ForwardingOs.getaddrinfo(ForwardingOs.java)
//framework层
libcore.io.Posix.getaddrinfo(Posix.java)
//JNI层,此方法为java的代理
Posix_android_getaddrinfo(Posic.cpp)
//调用BIONIC的libc标准库
android_getaddrinfofornet(getaddinfo.c)
android_getaddrinfofornetcontext(getaddinfo.c)
...

发送socket包...

2. HTTP DNS 与 native DNS 的流水生产线比较

使用http与native的分歧首要在:

  • 内需贯彻native 自带的 LRU缓存(DNS暗中同意是600s,原生的缓存在JNI内部存储器中,而OkHttp缓存在硬盘中)
  • Socket央求拼装环节在java层,并非在libc库中(当然某个项目非要做成JNI,也不可能)
  • 亟待维护多少个单身的HttpClient举行DNS查询

在进展落到实处前,我们先看下原生状态的查询办法的strace

本文由澳门新葡萄京所有网站发布于葡亰导航站,转载请注明出处:OkHttp3应用[HTTP DNS的实现]

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。