【前五篇】系列文章传送门:网络协议12-HTTP协议:常用但不简单的网络协议13-HTTPS协议:加密路上走不完??的网络协议14-流媒体协议:好不容易说出我爱你网络协议15-P2P协议:小种子大学网络协议16-DNS协议:网络世界的通讯录全球统一的DNS很权威,但是大家都知道“适合对我们来说,是最好的。”很多时候,标准统一的DNS并不能满足我们定制化的需求,这时候就需要HTTPDNS了。上一节我们了解到DNS可以根据名称查找地址,也可以对多个地址进行负载均衡。然而,我们信任的地址簿也可能指向错误的方向。离你500米就有吃饭的地方,但我不得不推荐你5公里外。为什么会出现这种情况?你是否记得?当我们发送解析DNS的请求时,首先会连接到运营商本地的DNS服务器,这台服务器会在整个“DNS树”上帮我们解析,然后将解析的结果返回给客户端。但是本地DNS服务器,作为本地导游,往往有自己的“小心思”。传统DNS存在的问题1)域名缓存问题可以做本地缓存。也就是说,并不是每次请求都会去权威的DNS服务器,而是在本地缓存一次访问的结果,别人来请求的时候直接返回缓存的内容。这就相当于一个导游去过饭店,自己把地址背下来了。游客问起,他会凭记忆回答,不用查通讯录。这样就会有问题。如果游客询问的餐厅已经搬走,但由于导游还没有刷新“内存缓存”,游客就白走了一趟。另外,有些运营商会在运营商的服务器中缓存一些静态页面,这样用户请求的时候,就不需要跨运营商访问,这样既加快了速度,也降低了运营商直接流量计算的成本.也就是说,当域名被解析时,用户不会被引导到真实的网站,而是被引导到缓存的服务器。缓存的问题很多时候是看不见的,但是当页面更新,用户访问旧页面的时候,问题就出来了。然后是本地缓存,经常会导致全局负载均衡失效。上次做缓存的时候,缓存中的地址可能不是本次客户来访时距离客户最近的地方。如果把这个地址退回给客户,客户就会绕道而行。2)域名转发问题大家还记得我们域名解析的过程吗?无论是在本地域名解析还是在权威DNS服务器中查找,都可以认为是一种外包形式。有了请求,直接转发给其他服务进行分析。权威DNS服务器转发还好,但如果“偷懒”,转发给邻居服务器解析,就很容易造成跨运营商访问问题。就好比运营商A的客户访问自己运营商的DNS服务器,运营商A去权威的DNS服务器查询,就会找到客户的运营商A,返回一个部署在运营商A上的网站地址。这样,访问同一个操作符会快很多。但是如果运营商A偷懒,直接转发给运营商B,而不是转发给权威DNS,让运营商B去权威DNS服务器查询,这样就会让权威服务器误认为客户是运营商B的,而returna运营商B的服务器地址导致客户每次都跨运营商访问,访问速度会变慢。3)出口NAT问题?前面学习网关的时候,我们知道很多机房在出口的时候都会配置NAT,也就是网络地址转换,这样从这个网关出去的包就会被换成新的IP地址.在这种情况下,权威DNS服务器无法通过请求IP来判断客户属于哪个运营商,极有可能误判运营商,造成跨运营商访问。4)域名更新问题‖‖‖本地DNS服务器由不同地区的不同运营商独立部署。域名解析缓存的处理实现策略也有差异。有的会偷懒,忽略域名解析结构的TTL时间限制。权威DNS服务器解析变更时,解析结果对全网生效的周期很长。但是在某些场景下,在DNS切换中,对有效时间的要求比较高。例如,在双机房部署的情况下,DNS通常用于跨机房的负载均衡和容灾。当机房出现问题时,需要修改权威DNS,将域名指向新的IP地址。但是如果更新太慢,很多用户就会访问一次。5)解析延迟问题?从DNS查询过程来看,DNS查询过程需要递归遍历多个DNS服务器才能得到最终的解析结果,带来了一定的延迟,甚至解析超时。上面总结了DNS的五个问题。有问题就一定有解决办法,就像HTTPS协议因为HTTP的安全问题而流行起来一样。相应的还有HTTPDNS来解决上述的DNS问题。HTTPDNS什么是HTTPDNS?其实很简单:HTTPDNS是一种基于HTTP协议和域名解析的流量调度方案。它不是传统的DNS解析,而是基于HTTP协议构建自己的DNS服务器集群,分布在多个地点和多个运营商。当客户端需要DNS解析时,直接通过HTTP请求服务器集群获取最近的地址。这相当于各个公司基于HTTP协议实现自己的域名解析,制作自己的通讯录,而不是使用统一的通讯录。但是我们知道域名解析默认使用DNS,所以使用HTTPDNS需要绕过默认的DNS路径,所以不能使用默认的客户端。**使用HTTPDNS往往是手机端应用,需要在手机端嵌入支持HTTPDNS的客户端SDK。HTTPDNS?的工作流程接下来,让我们一起了解一下HTTPDNS的工作流程。HTTPDNS会在客户端的SDK中动态请求服务器,获取HTTPDNS服务器的IP列表,缓存到本地。随着域名的不断解析,SDK也会在本地缓存DNS域名解析结果。当手机应用要访问一个地址时,首先检查本地是否有缓存,有则直接返回。该缓存与本地DNS缓存的区别在于,这是由移动应用程序本身完成的,而不是由整个运营商完成的。如何以及何时更新缓存,移动应用程序的客户端可以与服务器协调来执行此操作。如果本地没有,则需要请求HTTPDNS服务器。在本地HTTPDNS服务器的IP列表中,选择一个发送HTTP请求,获取您要访问的网站的IP列表。请求方式是这样的:curlhttp://123.4.5.6/d?dn=c.m.cnb...手机客户端,运营商和地址是手机所在的。因为是直接HTTP通信,HTTPDNS服务器可以准确的知道这些信息,所以可以做准确的全局负载均衡。以上五个问题归结为两个大问题。一是分析速度和更新速度的平衡,二是智能调度。HTTPDNS对应的解决方案是HTTPDNS的缓存设计和调度设计。HTTPDNS的缓存设计?为了加快解析速度,有缓存,但是这样会造成缓存更新速度不及时的问题。最要命的是这两方面都掌握在别人手里,也就是本地的DNS服务器。它不会为您定制??它,作为客户没有办法担心它。而HTTPDNS就是把解析速度和更新速度控制在自己手里。一方面,解析过程不需要大循环递归调用本地DNS服务,直接一个HTTP请求即可。当您想实时更新时,它会立即起作用。另一方面,为了提高解析速度,还有一个本地缓存。缓存在客户端SDK中维护,过期时间和更新时间可自行控制。HTTPDNS的缓存设计策略也是我们应用架构中常见的缓存设计模式,分为客户端、缓存、数据源三层。对于应用程序架构,它意味着应用程序、缓存和数据库。常见的有Tomcat、Redis、Mysql;对于HTTPDNS,它们是移动客户端、DNS缓存和HTTPDNS服务器。只要是缓存模式,都会存在缓存过期、更新、不一致等问题,解决方法也大同小异。比如DNS缓存在内存中,也可以持久化到存储中,这样APP重启后,可以第一时间从存储中加载上次累积的频繁访问网站的分析结果,而不用去解析alleverytime,然后变成缓存。这有点像Redis是一个基于内存的缓存,但是它也提供了持久化能力,这样在重启或者主备切换的时候数据不会完全丢失。SDK中的缓存会严格遵循缓存过期时间。如果缓存未命中或已过期,且客户端不允许过期的概率,则将发起决议以确保更新缓存记录。解析可以同步进行,即直接调用HTTPDNS接口,返回最新记录,更新缓存。也可以异步完成,在后台加一个解析任务,后台任务调用HTTPDNS接口。同步更新的优点是实时。缺点是如果发现多个请求过期,会同时请求多次HTTPDNS,造成资源浪费。同步更新方式对应应用架构缓存的Cache-Aside机制,即先读缓存,漏读数据库,同时将结果写入缓存。异步更新的好处是可以发现多个请求过期,合并成一个HTTPDNS的请求任务,只执行一次,减轻HTTPDNS的压力。同时可以在快过期的时候创建一个任务进行预加载,防止过期后被刷新,称为预加载。它的缺点是当当前请求获取过期数据时,如果客户端允许过期时间,则需要承担风险。这个风险意味着如果过期的请求还能被请求,就没事了。如果不能请求,就会失败一次,只有在下次缓存更新后请求才会成功。异步更新机制对应应用架构缓存的Refresh-Ahead机制,即业务仅在缓存过期时访问缓存并定期刷新。在大家熟知的应用缓存GuavaCache中,有一个RefreshAfterWrite机制。在并发的情况下,可以采用多次缓存访问未命中和请求回源,只请求一次回源的方式。在应用架构的缓存中,也经常会用到数据预热或预加载的机制。HTTPDNS的调度设计是因为客户端内嵌了SDK,所以权威DNS服务器不会因为本地DNS的各种缓存、转发、NAT等而误读客户端的位置和运营商,从而掌握第一手资料可以获得。在客户端可以知道手机在哪个国家,哪个运营商,哪个省,甚至哪个城市。HTTPDNS服务器可以根据这些信息选择最好的服务节点返回。如果有多个节点,错误率、请求时间、服务器压力、网络状况等也会综合考虑选择,而不仅仅是地理位置。当节点宕机或性能下降时,可以尽快切换。为此,客户端需要使用HTTPDNS返回的IP来访问业务应用程序。客户端的SDK会收集网络请求数据,如错误率、请求时间等网络请求质量数据,并发送到统计后台进行分析汇总,从而查看不同IP的服务质量。在服务器端,应用程序可以通过调用HTTPDNS的管理接口来配置不同服务质量的优先级和权重。HTTPDNS会根据地理位置和线路情况,根据这些策略计算出一个排名,优先访问当前优质低延迟的IP地址。HTTPDNS通过智能调度返回的结果也会缓存在客户端。为了不让缓存扭曲调度,客户端可以根据不同移动网络运营商的SSID进行不同维度的缓存。不同的算子解析出来的结果会不一样。总结传统DNS会因为缓存、转发、NAT等问题,导致客户端对自身所在位置和运营商产生误解,从而影响流量调度;HTTPDNS利用客户端SDK和服务端通过HTTP直接调用DNS解析,绕过了传统DNS的缺点,实现了智能调度。参考:HTTPDNS的原理;刘超-网络协议趣谈系列;
