在 DNS 查询 篇中,主要是根据阮一峰老师的文章所做的学习记录。讲述了通过命令 dig
来跟踪域名的查询过程,也提到了 DNS 服务器的层级结构、DNS 记录、DNS 缓存等。整体都是文字叙述,读起来会稍微有些累。这篇会通过图示来进一步简化 DNS 的解析过程,并会提到 DNS 的另一项重要作用,负载均衡
。
DNS 服务器层级结构
首先我们来了解一下 DNS 服务器。主要有三种类型的 DNS 服务器:
根 DNS 服务器,它知晓顶级域名 DNS 服务器地址,全球只有 13 台。
顶级 DNS 服务器,它知晓次级域名 DNS 服务器地址,也就是权威服务器。
权威 DNS 服务器,返回主机 ip。
DNS 服务器的层级是树状结构,如下图所示:
DNS 域名解析
假设我们需要在浏览器上访问 https://www.baidu.com 网页,浏览器识别到访问的是个域名而不是 ip 地址时,会开始发起域名解析的过程。用户电脑上运行着 DNS 应用客户端,我们把它叫做本地 DNS 解析器。
首先我们先来回顾一下域名解析的整个过程,稍后会以图示的方式展现。
首先浏览器会查找缓存中是否有 https://www.baidu.com 对应的 ip 地址。如果有,皆大欢喜,直接返回,就可以进行 http 请求的发送了。如果没有,那么进行下一步。
委托 DNS 解析器进行解析。DNS 解析器查找操作系统中的缓存,如果有则直接返回,若没有到下一步。
查找本地 hosts 文件,是否有配置该域名对应的 ip。若有,则返回该 ip。
如果前 3 步都没获取到,则请求本地 DNS 服务器。它也会先查本地缓存,若没有则向根域名服务器发起查询。
本地 DNS 服务器地址会配置在本机。如果是采用 DHCP 动态获取 IP 地址的方式,那么一般会被配置为网络运营商的 DNS 服务地址;或者可以自己配置为非权威 DNS 服务器地址,比如 google 的 8.8.8.8
。
那么它如何知道根域名服务器的地址呢?很简单,根域名服务器数量少,其地址会配置在本地 DNS 服务器中。
接着,本地 DNS 服务器向根域名服务器查询
.com
域名的地址。根域名服务器管理顶级域名服务器的地址,比如.com/.cn/.net/.org
,然后返回对应顶级域名服务器的地址。然后,本地 DNS 服务器又会向顶级域名服务器发起查询。Hi,哥们,
baidu.com
域名的地址是多少?顶级域名服务器查找一番,返回权威域名服务器的地址。本地 DNS 服务器继续像权威服务器发起查询。Hi,小哥哥,
www.baidu.com
的 ip 地址是多少?这时,权威域名服务器会返回自己管辖区域内这台主机的 ip 地址。本地 DNS 服务器收到返回的 IP 地址,缓存到本地,返回给 DNS 解析器。解析器也会将结果缓存一份,然后返回给浏览器。
浏览器收到结果,也会进行缓存。至此,就完成了域名查询,拿到了 IP 地址。
整体流程如下图所示,其中白色箭头表示查询方向,绿色箭头表示返回方向。
负载均衡
DNS 的另一个作用是做负载均衡,Server Load Balance
。
简单负载均衡
最简单的一种应用情况,在 DNS 服务器上配置某个域名对应的 ip 时,可以配置多个 A 记录,即一个域名对应多个 ip。这里可以配置不同的策略。
- 返回全部 ip
当客户端请求域名解析时,DNS 服务器返回全部 ip 地址。客户端拿到多个 ip 后可进行轮询,或者是随机选择一个 ip,或者是按照某种算法选择一个 ip 进行请求。
- 轮询返回 ip
假设配置了 ip1, ip2, ip3 三个地址。第一次请求返回 ip1,第二次请求返回 ip2,以此类推。
- 根据设置的权重返回 ip
设定各个 ip 的权重,优先返回权重大的 ip。
全局负载均衡
另外一种复杂的应用情况,做全局的负载均衡,即 GSLB,Global Server Load Balance
。全局上可分为运营商和区域,在同一个运营商上进行访问肯定速度更快;同样,请求的服务器距离客户端越近,速度越快。
那全局负载均衡如何实现呢?跟添加中间层的思想差不多,经过中间层 GSLB
来控制负载均衡策略。下面介绍两种方式。
- 添加 NS 记录,GSLB 充当权威 DNS 服务器
具体做法是,在权威 DNS 服务器上给目标域名配置一条 NS
记录,A → B
,即 A 对应的域名服务器地址为 B,也就是 GSLB 的地址
,让 GSLB
来充当权威域名服务器
。
当 DNS 解析 A 域名时,会返回设置好的 B。这样本地 DNS 服务器就会转到请求 B 也就是 GSLB
去进行域名解析,GSLB
就可按照某种策略进行负载均衡计算,比如根据本地 DNS 服务器的所属运营商和本地 DNS 服务器的位置返回合适的 ip。
假设查询的目标域名为 http://www.company.com
,设置一条 NS 记录为 http://www.company.com → http://www.companyOk.com
。那么当查询 www.company.com
时,DNS 服务器会返回 www.companyGSLB.com
。然后本地 DNS 服务器会去请求 www.companyGSLB.com
DNS 服务器,让该权威域名服务器去解析 www.company.com
域名,返回合适的 ip 地址。这样,控制权就交到了 www.companyGSLB.com
手上,具体策略可以由它自己来确定。
但是这种方式只能知道本地 DNS 服务器所属的运营商和 ip 地址,而不是客户端的 ip。
流程如下图所示:
- 添加 CNAME 记录
通过给域名添加别名的方式来实现,有两种不同的方式。
a. 设置别名后,再通过 http 重定向
给目标域名 A 配置别名 CNAME,也就是 GSLB 的域名。这样请求解析 A 域名时会返回 CNAME 记录,之后本地 DNS 服务器会转为请求 GSLB 的域名,最后返回 GSLB 的 ip 地址。
这样,客户端就会跟 GSLB 进行通信,GSLB 可以知道客户端的 ip 地址,进而根据一系列的策略进行调度,然后利用 http 重定向将客户端定向到合适的地址。
流程如下图所示:
b. 设置别名,通过 NS 记录转到不同的 GSLB 域名服务器
给目标域名设置别名,对别名设置 NS 记录,转到不同的 GSLB 去查询。
举个栗子:比如在 company.com
的权威服务器上给域名 test.company.com
设置别名 hello.test.comany.com。
当本地 DNS 服务器请求解析 test.company.com
时,流程如下:
经过一系列过程后,
company.com
权威 DNS 服务器会返回hello.test.comany.com
,告诉本地 DNS 服务器去解析该域名。本地 DNS 服务器进而去请求解析
hello.test.comany.com
的域名。company.com
的权威 DNS 服务器会配置一条 NS 记录,对应hello.test.comany.com
→xx.GSLB1.com
,告诉本地 DNS 服务器去xx.GSLB1.com
去解析域名。由于
xx.GSLB1.com
就是全局负载均衡服务器,它就可以根据客户端本地 DNS 服务器所在的运营商/位置返回合适的 ip。
流程图如下:
这里只有一层 GSLB,也可以有多层。假设第一层 GSLB 是用来区分运营商,第二层 GSLB 是区分区域。
比如本地 DNS 服务器所在运营商是移动,那么在 xx.GSLB1.com
就可返回另一个别名 yd.test.comany.com
。yd.test.comany.com
也对应一条 NS 记录,yd.test.comany.com
→ xx.GSLB2.com
,这样就将 yd.test.comany.com
转到第二层 GSLB 去解析。GSLB2
就可根据本地 DNS 服务器的位置返回距离用户较近区域的 ip。