每个人上网,都需要访问 DNS,一旦它出了故障,整个互联网都将瘫痪。另外,上网的人分布在全世界各地,如果大家都去同一个地方访问某一台服务器,时延将会非常大。因而,DNS 服务器,一定要设置成高可用、高并发和分布式的。
DNS 的层次结构
DNS 采用如下的树状的层次结构:
- 根 DNS 服务器 :返回顶级域 DNS 服务器的 IP 地址
- 顶级域 DNS 服务器:返回权威 DNS 服务器的 IP 地址
- 权威 DNS 服务器 :返回相应主机的 IP 地址
DNS 解析域名的过程
下面我们以浏览器使用域名访问网站为例来阐述 DNS 解析域名的过程。
-
检查浏览器缓存中是否缓存过该域名对应的IP地址,这个缓存是有过期时长的,一般是几分钟到几小时不等
用户通过浏览器浏览过某网站之后,浏览器就会自动缓存该网站域名对应的地址,当用户再次访问的时候,浏览器就会从缓存中查找该域名对应的IP地址,因为缓存不仅是有大小限制,而且还有时间限制(域名被缓存的时间通过属性来设置),所以存在域名对应的找不到的情况。当浏览器从缓存中找到了该网站域名对应的地址,那么整个解析过程结束,如果没有找到,将进行下一步骤。
对于的缓存时间问题,不宜设置太长的缓存时间,时间太长,如果域名对应的发生变化,那么用户将在一段时间内无法正常访问到网站,如果太短,那么又造成频繁解析域名。
-
如果在浏览器缓存中没有找到IP,那么将继续查找本机系统的 hosts 文件是否缓存过
对于 Linux 来说,这个文件是 /etc/hosts。
对于 Windows 来说,这个文件是 C:\Windows\System32\drivers\etc\hosts
如果第一个步骤没有完成对域名的解析过程,那么浏览器会去系统的 hosts 文件查找系统是否缓存过这个域名对应的地址,也可以理解为系统自己也具备域名解析的基本能力。在系统中,可以通过设置文件来将域名手动绑定到某个 IP 地址上。
对于普通用户,并不推荐自己手动绑定域名和,对于开发者来说,通过绑定域名和,可以轻松切换环境,可以从测试环境切换到开发环境,方便开发和测试。
-
向本地域名解析服务系统发起域名解析的请求
如果本地也没有配置那么就会根据向本机配置的本地域名服务器(LDNS)发起请求。比如你连接的校园网,那么本地域名解析系统就在你的校园机房里,如果你连接的是电信、移动或者联通的网络,那么本地域名解析服务器就在本地区,由各自的运营商来提供服务。
本地域名服务器一般都缓存了大部分的域名解析的结果,当然缓存时间也受域名失效时间控制,大部分的解析工作到这里就差不多已经结束了,到这一步基本能解析 80% 的域名。
-
本地域名服务器向根域名解析服务器发起域名解析请求
根域名解析服务器是最高层次的,全球共有 13 套,它不直接用于域名解析,它会根据域名的后缀返回对应的国际顶级域名服务器(gTLD)的地址。比如,.com 的后缀就会返回 .com 对应的国际顶级域名服务器地址。
-
本地域名服务器向国际顶级域名服务器(gTLD)发起域名解析请求
本地域名服务器 LDNS 再向上一步返回的 gLTD 服务器发送请求。gLTD 服务器查询并返回负责管理该域名的权威 DNS 服务器的地址。假如你在某个域名服务器提供商申请的域名,那么这个权威 DNS 服务器就由这个域名服务提供商来完成。具体点,multiparam.com 这个域名是在阿里云注册的,那么权威域名服务器就是阿里云提供的。
-
本地域名服务器向权威 DNS 服务器发起域名解析请求
权威 DNS 服务器查找域名对应的地址,将地址连同一个 TTL 值返回给本地域名服务器。
-
本地域名服务器缓存解析结果
本地域名服务器缓存解析后的结果,缓存时间由 TTL 值控制。
-
返回解析结果给用户
用户根据 TTL 值将解析结果缓存在本地系统缓存中,域名解析过程结束。
DNS 实现负载均衡
站在客户端角度,这是一次 DNS 递归查询过程。因为本地 DNS 服务器全权为它效劳,它只要坐等结果的返回即可。其实在这个过程中,本地 DNS 除了可以通过名称映射为 IP 地址,它还可以进行负载均衡,包括内部负载均衡和全局负载均衡。
下面我们通过 DNS 访问数据中心中对象存储上的静态资源为例,来看一看整个实现负载均衡的过程。
假设全国有多个数据中心,这些数据中心分布在多个运营商中,可以理解成每个运营商中都部署了多个数据中心。每个数据中心有三个可用区(Available Zone)。这样,对象存储可通过跨可用区部署,实现高可用性。在每个可用区中都至少部署两个内部负载均衡器(Server Load Balance),内部负载均衡器后面对接多个对象存储的前置服务器(Proxy-Server)。
-
当一个客户端要访问 object.yourcompany.com 的时候,需要将域名转换为 IP 地址进行访问,所以这个请求需要使用本地 DNS 解析器。
-
本地 DNS 解析器先查看看本地的缓存是否有这个记录,如果有则直接使用。
-
如果本地无缓存,则需要请求本地的 DNS 服务器。本地的 DNS 服务器一般部署在你所在的运营商的网络中,本地 DNS 服务器也需要看本地是否有缓存,如果有则返回。
-
如果本地没有,本地 DNS 才需要递归地从根 DNS 服务器,查到 .com 的顶级域名服务器,最终查到负责 yourcompany.com 的权威 DNS 服务器,给本地 DNS 服务器。
-
之后,本地 DNS 服务器会向权威 DNS 服务器发出域名解析请求。对于不需要做全局负载均衡的简单应用来讲,yourcompany.com 的权威 DNS 服务器可以直接将 object.yourcompany.com 这个域名解析为一个或者多个 IP 地址,然后客户端可以通过多个 IP 地址,进行简单的轮询,实现简单的负载均衡。
但是对于复杂的应用,尤其是跨地域跨运营商的大型应用,它们需要更加复杂的全局负载均衡机制,因而需要专门的设备或者服务器来做这件事情,这就是全局负载均衡器(GSLB,Global Server Load Balance)。
这个时候可以给目标域名设置 CHAME,然后对 CHAME 设置 NS 记录,从而可以转去 GSLB 进行解析。比如,可以在负责 yourcompany.com 的权威 DNS 服务器上给 object.yourcompany.com 起一个别名,例如 object.vip.yourcomany.com。这样,本地 DNS 服务器请求解析 object.yourcompany.com 的时候会返回 object.vip.yourcomany.com。本地 DNS 服务器会去解析 object.vip.yourcomany.com 这个域名。那么,可以给这个域名配置一个 NS 记录,比如 object.vip.yourcomany.com -> GSLB1.com(NS(Name Server)记录,是域名解析中的一种记录类型。 域名解析中设置增加NS 记录后,会指定该域名由哪个DNS 服务器来进行解析(NS 记录的值为DNS 服务器))。这样本地 DNS 会去 GSLB1.com 解析object.vip.yourcomany.com 这个域名,而 GSLB 在解析这个域名的过程中,可以通过自己的策略实现负载均衡。
除了采用 CHAME 之外,还可以采用直接配置 IP 地址,或者在 CHAME 解析成功之后,让客户端直接跟 GSLB 进行交互。
如图所示画了两层的 GSLB,是因为分运营商和地域。我们希望不同运营商的客户,可以访问相同运营商机房中的资源,这样不跨运营商访问,有利于提高吞吐量,减少时延。
- 第一层 GSLB,通过查看向它发出请求的本地 DNS 服务器所在的运营商,就知道用户所在的运营商。假设是移动,再次通过 CNAME 的方式,通过另一个别名 object.yd.yourcompany.com,告诉本地 DNS 服务器去请求第二层的 GSLB。
- 第二层 GSLB,通过查看向它发出请求的本地 DNS 服务器所在的地址,就知道用户所在的地理位置,然后将距离用户位置比较近的 Region 里面的六个内部负载均衡(SLB,Server Load Balancer)的地址,返回给本地 DNS 服务器。
-
本地 DNS 服务器将结果返回给本地 DNS 解析器。
-
本地 DNS 解析器将结果缓存后,返回给客户端。
-
客户端开始访问属于相同运营商的距离较近的 Region 1 中的对象存储,当然客户端得到了六个 IP 地址,它可以通过负载均衡的方式,随机或者轮询选择一个可用区进行访问。对象存储一般会有三个备份,从而可以实现对存储读写的负载均衡。