基于OkHttp3 加入HttpDns功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于OkHttp3 加入HttpDns功能相关的知识,希望对你有一定的参考价值。

参考技术A HttpDns是通过网络请求的方式,获取即将发送的业务请求所需要的ip地址。

在使用HttpDns时,android发送网络请求时会请求本地dns或本地运营商 的dns服务获取目标ip,但是一旦你使用的这个默认的dns不靠谱,不受信任,则请求稳定性将会降低,甚至可能被劫持。
因此,如果能够使用自己信任的dns服务器做dns域名解析,将大大降低这种风险。

OkHttp3一大亮点在其强大的Interceptor机制。因此HttpDns在整个request发射过程中就有了两个结合点:

使用Interceptor做ip直连,则会存在以下优点:

若使用OkHttp自带的dns(),优点在于:

综上来看,使用OkHttp原生Dns接口更加科学。除非不要求Cookie,不使用Https,使用Interceptor做简单的场景才比较合适。

OkHttp内使用 RouteDatabase 进行每次使用ip的监控和反馈:

为了能够复用 shouldPostpone() 获取okhttp自身对ip可用性的判断结果,使得自定义manager对ip的可用性的判断与okhttp一致,从而更新Manager自身的ip名单,可以通过
Internal.instance.routeDatabase(getConnectionPool()); 得到RouteDatabase对象。

Internal.instance 在OkHttpClient实例化之后就被赋值,事实上,Internal.instance就是OkHttpClient。因此可以使用NetworkInterceptor获取RouteDatabase。即:

Manager内维护两个名单Map,

interceptors.addAll(client.interceptors()) 是将addInterceptor时的所有Interceptor加入列表,然后再加入OkHttpCore核心处理Interceptor。
如果本次请求是一个需要走网络的请求,还会继续添加addNetInterceptor时所有的Interceptor加入列表。最后才加入CallServerInterceptor用来处理真正的网络请求。
这个顺序能够保证在递归调用过程中,自定义拦截器只会影响到OkHttpCore处理流程之前或者之后,而Core内的核心流程不会受到影响。

HttpDNS功能说明及实现

参考技术A HTTPDNS使用HTTP协议进行域名解析,代替现有基于UDP的DNS协议,域名解析请求直接发送到阿里云的HTTPDNS服务器,从而绕过运营商的Local DNS,能够避免Local DNS造成的域名劫持问题和调度不精准问题。

HTTPDNS代替了传统的LocalDNS完成递归解析的功能,基于HTTP协议的设计可以适用于几乎所有的网络环境,同时保留了鉴权、HTTPS等更高安全性的扩展能力,避免恶意攻击劫持行为。

传统域名解析的调度精准性问题,本质根源在于Local DNS的部署和分配机制上。由于碎片化的管理方式,这些环节的服务质量同样很难得到保障。HTTPDNS在递归解析实现上优化了与权威DNS的交互,通过<a name="https://datatracker.ietf.org/doc/rfc7871">edns-client-subnet</a>协议将终端用户的IP信息直接交付给权威DNS,这样权威DNS就可以忽略Local DNS IP信息,根据终端用户的IP信息进行精准调度,避免Local DNS的坐标干扰

服务端提供API接口,app端直接通过ip地址访问,ip地址可以有多个

请求方式:HTTP GET

URL参数说明:

请求示例:

考虑到服务IP防攻击之类的安全风险,为保障服务可用性,HTTPDNS同时提供多个服务IP,当某个服务IP在异常情况下不可用时,可以使用其它服务IP进行重试。

错误码列表如下:

异常下的出错兼容逻辑,主要包括异步请求,重试,降级

异步请求

重试

降级

OkHttp默认使用系统DNS服务InetAddress进行域名解析,但同时也暴露了自定义DNS服务的接口,通过该接口我们可以优雅地使用HttpDns。

OkHttp暴露了一个Dns接口,通过实现该接口,我们可以自定义Dns服务:

创建OkHttpClient对象,传入OkHttpDns对象代替默认Dns服务:

相比于通用方案,OkHttp+HttpDns有以下两个主要优势:

基于NSURLProtocol可拦截iOS系统上基于上层网络库NSURLConnection/NSURLSession发出的网络请求;

通过以下接口注册自定义NSURLProtocol,用于拦截上层网络请求,并创建新的网络请求接管数据发送、接收、重定向等处理逻辑,将结果反馈给原始请求。

自定义NSURLProtocol处理过程概述:

以上是关于基于OkHttp3 加入HttpDns功能的主要内容,如果未能解决你的问题,请参考以下文章

实现简单的httpDNS的一种思路

优雅设计封装基于Okhttp3的网络框架:多线程单例模式优化 及 volatile构建者模式使用解析

优雅设计封装基于Okhttp3的网络框架:HttpHeader接口设计实现 及 ResponseRequest封装实现

HttpDns原理

优雅设计封装基于Okhttp3的网络框架:多线程下载添加数据库支持(greenDao)及 进度更新

优雅设计封装基于Okhttp3的网络框架(完):原生HttpUrlConnction请求多线程分发 及 数据转换