type
status
date
slug
summary
tags
category
icon
password
Sub-item
Last edited time
Oct 29, 2023 02:09 AM
Parent item
领域
DNS(Domain Name System,域名系统),DNS 服务用于在网络请求时,将域名转为 IP 地址。能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。
DNS主要有两项功能:
- 根据名称查到具体的地址。
- 可以针对多个地址做负载均衡,而且可以在多个地址中选择一个距离你近的地方访问。
当我们发出请求解析DNS的时候,首先,会先连接到运营地本地的DNS服务器,由这个服务器帮我们去整理整颗DNS树上进行解析,然后将解析的结果返回给客户端。但是本地DNS服务器,有自己的“小缺陷”。
1域名缓存问题
它可以在本地做一个缓存,也就是说,不是每一个请求,它都会去访问权威DNS服务器,而是访问过一次就把结果缓存到自己本地,当其他人来访问的时候,直接就返回这个缓存数据。
就相当于它只是凭着记忆来回答这个问题而不是实际去查,这样就导致原来的地址可能已经搬走了但是并没有刷新这个缓存,导致找不到。
在就是本地的缓存,往往使得全局负载均衡失败,因为上次进行缓存的时候,缓存的地址不一定是这次访问离客户最近的地方,如果把这个地址返回给客户,可能会绕远路。
2域名转发问题
缓存问题还可以说本地域名解析服务,还是会去权威DNS服务器中查找,只不过每次都要查找。但是有些小运营商有了请求之后,直接转发给其他运营商去解析,自己自己外包了出去。
这样的问题是,如果是A运营商的客户,访问自己运营商的DNS服务器,如果A运营商去权威DNS服务器查询的话,权威DNS服务器知道你是A运营商的,就返回一个部署在A运营商的网站地址,这样针对相同运营商的访问,速度就会快很多。
但是A运营商偷懒,将解析的请求转发给B运营商,B运营商就会去权威DNS服务器查询的话,权威服务器就会认为,你是B运营商的,那就返回给你一个在B运营商的网站地址吧,结构客户端每次访问都要跨运营商,速度就会很慢。
3出口NAT问题
网关出口的时候,很多机房都会配置NAT,也就是网络地址转换,使得从这个网关出去的包,都转成新的IP地址,当然请求返回的时候,在这个网关,再将IP地址转换回去。所以对于访问来讲是没有任何问题的。
但是一旦做了网络地址转换,权威的DNS服务器,就没法通过这个地址,来判断客户到达来自哪个运营商,而且极有可能因为转换后的地址,误判运营商,导致跨运营商访问。
4域名更新问题
本地DNS服务器是由不同地址,不同运营商独立部署的,对域名解析缓存的处理上,实现策略也有区别。有的会偷懒,忽略域名解析结果的TTL时间限制,在权威DNS服务器解析变更的时候,解析结果在全网生效的周期非常漫长。但是有的时候,在DNS的切换中,场景对生效时间要求比较高。
比如双机房部署的时候,跨机房的负载均衡和容灾多使用DNS来做。当一个机房出现问题之后,需要修改权威DNS,将域名指向新的IP地址,但是如果更新太慢,那很多用户访问都会出现异常。
5解析延迟问题
DNS的查询过程需要递归遍历多个DNS服务器,才能获得最终的解析结果,这会带来一定的时延,甚至会解析超时。
上面五个问题,归结起来就两大问题。
- 解析速度和更新速度的平衡问题
- 智能调度的问题
除了上面2个问题,HttpDns 还解决:
- Local DNS 劫持:由于 HttpDns 是通过 IP 直接请求 HTTP 获取服务器 A 记录地址,不存在向本地运营商询问 domain 解析过程,所以从根本避免了劫持问题。
- 平均访问延迟下降:由于是 IP 直接访问省掉了一次 domain 解析过程,通过智能算法排序后找到最快节点进行访问。
- 用户连接失败率下降:通过算法降低以往失败率过高的服务器排序,通过时间近期访问过的数据提高服务器排序,通过历史访问成功记录提高服务器排序。
HTTPDNS
既然DNS有那么多问题,那怎么办呢?难道退回到直接用IP地址?这显然不合理。于是有了HTTPDNS。
HTTPDNS 利用** HTTP 协议与 DNS 服务器交互**,代替了传统的基于 UDP 协议的 DNS 交互,绕开了运营商的 Local DNS,有效防止了域名劫持,提高域名解析效率。另外,由于 DNS 服务器端获取的是真实客户端 IP 而非 Local DNS 的 IP,能够精确定位客户端地理位置、运营商信息,从而有效改进调度精确性。
HTTPDNS其实就是,不走传统的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 列表。
请求的方式是这样的:
HTTPDNS 的缓存设计
解析 DNS 过程复杂,通讯此时多,对解析速度形成很大影响。为了加快解析,于是有了缓存,可是这又会产生缓存更新速度不及时的问题。最要命的是,这两个方面都掌握在别人手中,也就是本地 DNS 服务器手中,它不会为你定制,做为客户端干着急也没办法。
而 HTTPDNS 就是将解析速度和更新速度所有掌控在本身手中。
- 解析的过程,不须要本地 DNS 服务递归的调用一大圈,一个 HTTP 的请求直接搞定。要实时更新的时候,立刻就能起做用。
- 为了提升解析速度,本地也有缓存,缓存是在客户端 SDK 维护的,过时时间、更新时间,均可以本身控制。
HTTPDNS 的缓存设计策略也是我们作应用架构中经常使用的缓存设计模式,也即分为客户端、缓存、数据源三层。
- 对于应用架构来说,就是应用、缓存、数据库。常见的是 Tomcat、Redis、Mysql;
- 对于 HTTPDNS 来说,就是手机客户端、DNS 缓存、HTTPDNS 服务器。
只要是缓存模式,就存在缓存的过时、更新、不一致的问题,解决思路也是类似的。
例如,DNS 缓存在内存中,也能够持久化到存储上,从而 APP 重启以后,可以尽快从存储中加载上次累积的常常访问的网站的解析结果,就不须要每次都所有解析一遍,再变成缓存。这有点像 Redis 是基于内存的缓存,可是一样提供持久化的能力,使得重启或者主备切换的时候,数据不会彻底丢失。
SDK 中的缓存会严格按照缓存过时时间,若是缓存没有命中,或者已通过期,并且客户端不容许使用过时的概率,则会发起一次解析,保证缓存记录是更新的。
解析方式:
- 同步进行,也就是直接调用 HTTPDNS 的接口,返回最新的记录,更新缓存。优势是实时性好,缺点是若是有多个请求都发现过时的时候,会同时请求 HTTPDNS 屡次,形成资源浪费。
同步更新的方式对应到应用架构缓存的 Cache-Aside 机制,也就是先读缓存,不命中读数据库,同时将结果写入缓存。
- 异步进行,添加一个解析任务到后台,由后台任务调用 HTTPDNS 的接口。优势是能够将多个请求都发现过时的状况,合并为一个对于 HTTPDNS 的请求任务,只执行一次,减小 HTTPDNS 的压力。同时,能够在即将过时的时候,就建立一个任务进行预加载,防止过时以后再刷新,称为预加载。它的缺点是,当前请求拿到过时数据的时候,若是客户端容许使用过时数据,须要冒一次风险。此次风险是指,若是过时的请求还能请求,就没问题,若是不能请求,就会失败一次,等下次缓存更新后,才能请求成功。
异步更新的机制,对应到应用架构缓存的 Refresh-Ahead 机制,即业务仅仅访问缓存,当过时的时候按期刷新。在著名的应用缓存 Guava Cache 中,有个 RefreshAfterWrite 机制,对于并发状况下,多个缓存访问不命中从而引起并发回源的请求,能够采起只有一个请求回源的模式。在应用架构的缓存中,也经常用数据预热或者预加载的机制。
HTTPDNS 的调度设计
因为客户端嵌入了 SDK,于是就不会由于本地 DNS 的各类缓存、转发、NAT,让权威 DNS 服务器误会客户端所在的位置和运营商,从而能够拿到第一手资料。
在客户端,能够知道手机是哪一个国家、哪一个运营商、哪一个省、甚至是哪一个市,HTTPDNS 服务端能够根据这些信息,选择最佳的服务节点返回。
若是有多个节点,还会考虑错误率、请求时间、服务器压力、网络状态等,进行综合选择,而非仅仅考虑地理位置。当有一个节点宕机或者性能降低的时候,能够尽快进行切换。
要作到这一点,须要客户端使用 HTTPDNS 返回的 IP 访问业务应用。客户端的 SDK 会收集网络请求数据,如错误率、请求时间等网络请求质量数据,并发送到统计后台,进行分析、聚合,以此查看不一样 IP 的服务质量。
在服务端,应用能够经过调用 HTTPDNS 的管理接口,配置不一样服务质量的优先级、权重。HTTPDNS 会根据这些策略综合地理位置和线路情况算出一个排序,优先访问当前那些优质的、时延低的 IP 地址。
HTTPDNS 经过智能调度以后返回的结果,也会缓存在客户端。为了避免让缓存使得调度失真,客户端能够根据不一样的移动网络运营商的 SSID 来分维度缓存。不一样的运营商解析出来的结果会不一样。