项目中视频播放被运营商DNS劫持。
当用户向Local DNS去请求某个域名的真实ip时,运营商的Local DNS服务器回复了一个假网站或内容缓存服务器的ip,最终导致用户访问无法访问到真实ip,从而出现异常。
使用HTTP协议向DNS服务器的80端口进行请求,代替传统的DNS协议向DNS服务器的53端口进行请求,绕开了运营商的Local DNS,从而避免了使用运营商Local DNS造成的劫持和跨网问题。
1.客户端向HttpDNS服务器发起请求(该请求为ip直连请求),获取与域名对应的一系列ip列表;
2.客户端从ip列表中选取访问延迟最优的ip,直接用此ip代替域名发送请求,这样就避免了Local DNS域名解析这一步骤。
采用dnspod 方案,具体参考:https://www.dnspod.cn/httpdns/guide
APPHttpDNS技术的接入过程:HttpDNS技术核心架构层、HttpDNS技术业务逻辑层和HttpDNS技术客户端容错处理。
1.客户端接收到域名请求,查询是否已有该域名历史解析结果缓存,如果已有解析结果缓存则转步骤2,否则转步骤3;
2.检查该缓存是否过期,如果没有过期,则返回查询结果,域名解析成功,否则转步骤3;
3.如果没有解析结果或缓存已过期,则向HttpDNS服务器(119.29.29.29)发起域名查询请求,如果请求成功则转步骤4,否则赚步骤5;
4.域名查询请求成功,得到一组ip列表,通过ip优化选择最优ip并返回查询结果,同时更新解析结果缓存;
5.域名查询请求失败,为了容错,必须再用Local DNS请求一遍,无论是否成功均返回,完成整个查询流程。
几乎所有的APP都涉及网络数据传输,这就需要有多个业务接口进行网络请求,如请求首页数据、请求列表数据、请求图片资源等,无论你是采用系统网络请求或是建有自己的网络库进行网络请求,想把域名直接替换为ip,无外乎以下方式:
如果你的业务异常独立,都采用同一个域名,那你可以通过预埋ip的方式完成这一过程;
如果你是自建网络库,所有的网络请求都由同一网络库发出,那么你可以在网络库中集中处理,通过提取接口中的域名,利用前面介绍的HttpDNS技术,把域名转换为ip,利用ip替换接口中的域名进行请求;
如果你的业务比较分散,网络请求没有集中整理,那就很难统一给HttpDNS一个域名,于是就有了DNS HOOK技术。
2.全局配置BGP-IP更新
一旦BGP-IP(HttpDNS服务器ip)不可用,HttpDNS的解析一定是出错的,这时候就需要有一个备用的BGP-IP来进行替换,从而走入正常流程之中。
3.预埋ip
通过预埋一些重要域名对应的ip列表,当解析出现错误的时候可以直接查找该域名是否有对应的预埋ip,如果查找到则采用预埋ip进行网络请求。预埋ip作为兜底处理,可以提高域名解析的正确率,但有可能出现该ip不可用或延时很长的情况。
4.域名自动过滤
我们的APP有需要外部依赖jar包,这些jar包中可能包含非常多的域名,然而有些域名我们可能不希望其也走入HttpDNS解析之中,于是提供了一个域名过滤的功能,只处理我们明确需要处理的域名解析。
5.特定域名解析失败一段时间内自动屏蔽功能
如果HttpDNS服务器出现对某个特定域名一直解析出错的情况,我们会缓存该域名的出错次数,一旦该域名解析出错三次,则禁止其在1个小时内再通过HttpDNS服务器进行解析,转而使用系统原生解析流程,从而消减解析耗时。
1.根治域名解析异常:由于绕过了运营商的LocalDNS解析,客户端的请求通过ip直连,彻底解决了域名劫持问题;
2.减少网络延迟:通过本地缓存ip,可以有效减少域名解析时间,降低用户网络请求的平均耗时;
3.提升网络请求可控性和可靠性:我们采用的HttpDNS服务器依托腾讯庞大的ip地址库,利用腾讯公网交换平台的BGP Anycast网络,大大提高了网络请求的可靠性,同时是否走HttpDNS以及BGP IP的选择均由后台控制,增加了可控性。