我们之前说了DNS的寻找流程,而且在DNS解析的过程中,说明了DNS可以对多个地址做负载均衡
但是直接使用DNS的话,很可能解析过程中出错
我们举一些常见的例子:
1.域名缓存问题
DNS会在查找后在本地做一个缓存,也就是每个请求,都不一定会去访问DNS服务器,有缓存的情况下,会优先返回缓存的数据
比如说,一些静态的页面,会被缓存到运营商的服务器中,但是这些静态页面是随时可能更新的,虽然在一般的使用过程中静态页面的缓存,能够加快访问的速度,减少了运营商之间的访问成本,但是如果静态页面更新了,那么就可能出现了问题,因为想要访问新页面的用户也是只能访问老的静态页面
而且本地的缓存,往往使得全局负载均衡失败,因为上次进行缓存的时候,缓存的地址不一定是这次访问中离客户比较近的地方,如果直接返回这个地址给客户,客户的访问不是最优选
2.域名转发问题
域名问题还是说本地域名解析服务,会去权威DNS服务器中查找,但是并非每次都会查找,而是有些时候,会发给其他的运营商去做解析,就好比,我是A运营商的客户,访问自己的运营商A的DNS服务器,然后A的DNS服务器会去访问权威服务器,权威服务器知道自己是A运营商的,会返回给你A运营商上的网站,这样是使用的相同运营商的访问,速度快得多
但是存在一些的问题,如果A运营商偷懒了,将解析的请求交给了B运营商,导致权威服务器一看,是B运营商发来的查询,于是返回了一个B运营商上的服务器,导致每次访问要跨运营商,速度很慢
前面讲述网关的时候,出口的时候,很多机房都配置了NAT,也就是网络地址转换,让这个网关出的包,都能换成新的IP地址,返回的时候,在这个网关,也将IP地址转换回去,这样做的话,我们在使用过程中没有办法,但是做了网络地址的转换,权威的DNS服务器可能在解析时候出错了,导致对于运营商判断错了
3.域名更新问题
本地DNS服务器,是由不同的地区上部署了不同的运营商之间部署的,在进行域名解析的时候,实现的策略有所不同,有的会偷懒,对于域名存在的TTL过期时间,经常不理会,这就导致,有些时候,DNS的切换,无法及时的生效
比如,我们做了双机热备.当一个机房出现了问题之后,需要修改权威的DNS,让其将域名只指向一个机房,但是这样更新了权威服务器,有的本地DNS服务器不认啊
4.解析的延迟问题
从上面的DNS查询汇总,可以看出DNS的查询需要多次遍历多个DNS服务器,才能获得最后解析结果,这就具有一定的延迟,甚至在传输的过程中,超时了
那么就是推出了HttpDns的工作模式
不进行传统的DNS的解析,而是自我搭建基于HTTP协议的DNS服务器集群,分布在多个地点和运营商中,当客户端需要DNS解析的时候,直接通过HTTP协议去请求这服务器集群,得到最近的地址
这就好比每家基于HTTP协议,自己实现自己的域名解析,而不用外部的DNS服务器,自己做一个自己的地址簿,而不是用统一的地址簿,这就需要在域名解析的时候,绕过默认的DNS得域名解析,直接走HttpDNS,这样比较容易实现的,就是手机应用
在手机端,通过自己的HttpDNS服务器和自己的SDK,能避免依赖本地的导游,进行自由行
那么Http DNS的工作流程
在客户端的SDK中动态的请求服务器端,获取到了HttpDNS服务器的IP列表,缓存到本地,然后伴随着不断的解析域名,SDK也会在本地缓存着DNS域名解析的结果
在访问一个地址的时候,会首先查看本地是否具有这个地址的缓存,有就直接返回,这和普通的DNS的是一样的,虽然这个查询的过程不是交给了本地DNS服务器,而是在自己的手机应用上做的,如果本地没有,就会请求HttpDNS的服务器,在本地HttpDNS的IP列表中,选择一个发出HTTP的请求,返回一个要访问的网站的IP列表
发出和返回分别为
curl http://106.2.xxx.xxx/d?dn=c.m.163.com |
{“dns”:[{“host”:”c.m.163.com”,”ips”:[“223.252.199.12″],”ttl”:300,”http2″:0}],”client”:{“ip”:”106.2.81.50″,”line”:269692944}} |
手机客户端和服务器连接的过程中,是直接的HTTP通信,HttpDNS服务器可以直接指导客户端的运营商,所在地址,做到负载均衡
当然,如果HttpDNS在请求Http服务器的过程中,不成功,如何解析?只能考虑切换到传统的LocalDNS来解析,做到虽然慢点,但是能解析
而且针对上面传统DNS的问题,HttpDNS做了些调整和优化
HttpDNS的缓存设计
解析DNS的过程很复杂,是一种递归调用,而且这个过程是由本地DNS服务器去管理的,这就没法去定制化的使用本地DNS服务器,毕竟他是共用的
HttpDNS就是将解析速度和更新速度放在了自己的手上,一方面,解析的过程中,不需要本地的DNS服务递归的调用一大圈,一个Http请求就能搞定,而且在更新的时候,请求立刻生效,而且为了提高解析速度,本地也有缓存,因为是自己维护的,所以可以控制过期时间,更新时间
HttpDNS的缓存设计的策略也是常见的缓存设计模式,分为了客户单 – 缓存 – 数据源
Dns缓存在内存中,也可以持久化到存储中,不用每次开关机都再走一次解析,而且在SDK中,缓存会严格的按照过期时间,如果缓存没有命中,或者过期了,而且客户端不能使用过期的记录,就会重新进行一次解析
解析分为同步解析,异步解析
同步解析,就是直接调用HttpDNS的接口,返回最新的记录,更新缓存,但是可能出现并发问题
异步进行就是添加一个解析任务到后台,由后台调用HttpDNS的接口,对于发现多个请求都过期的情况,就合并为一个HttpDNS的请求,而且在快过期的时候,就提前去预加载,防止过期后再刷新
异步刷新就好比应用架构中缓存的Refresh-Ahead机制,业务仅仅访问缓存,当快过期的时候定时刷新,在知名的应用缓存Guava Cache中,就有一个RefreshAfterWriye机制,在并发过程中,多个缓存不命中从而引发并发的回源的情况,只有一个请求真正的回源,在应用架构的缓存中,常有着其身影
HttpDNS的调度设计
因为是客户端直接发起的请求,那么就不会因为Nat和缓存导致解析错误
在客户端,可以直接知道手机是哪个国家,哪个运营商的信息,直接返回最佳的节点
如果有多个节点,还能考虑错误率,服务器压力,网络状况等,综合考虑,出现问题尽快的切换
如果要做到这一点,需要客户端使用HttpDNS返回的IP访问业务应用,客户端的SDK收集网络请求数据,比如错误率,请求时间等,返回给客户端后台,方便统计
服务器端,可以调用HttpDNS的管理接口,配置不同服务质量的优先级,权重等,HttpDNS返回的时候就有限返回优质的IP地址
HttpDNS通过智能调度后的返回结果,缓存在客户端,如果不让缓存实现,客户端可以根据不停的移动网络的WIFI来分维度缓存,让不同运营商的网络的解析结果不同
本章总结
传统的DNS有很多的问题,例如解析慢,更新不及时的问题,因为缓存,转发 NAT问题导致客户端误以为自己所在的位置和运营商,影响了传输的速度
HttpDNS通过客户端SDK和服务端,通过HTTP直接调用解析DNS的方式,绕过了传统DNS的缺点,实现了智能的调度
课后思考
1.使用HttpDNS,需要向HttpDNS服务器请求解析的域名,可是客户端怎么知道HttpDNS服务器的地址或者域名呢?
2.HttpDNS的智能调度,主要是让客户端选择最近的服务器,但是有另外的一种机机制,可以让资源提前分发到客户端,加快了客户端的访问,是什么技术?
1.httpdns的服务器地址一般不会改变,可以使用传统DNS的方式,去获取到httpDNS的服务器的ip地址,也可以直接把httpDNS服务器的IP地址写死在客户端中,就好比初始就写上HttpDNS
但是HttpDNS来说,虽然能够解决传统的DNS的问题,但是必须要有自己的客户端去连接HttpDNS,这种情况,就需要对业务进行全方面的改造,同样对于浏览器访问,也需要自己的HttpDNS的客户端
2.使用的是CDN技术