Introduction
网络方面的知识之前一直介绍的比较少,今天就从最基础的DNS开始分享下,主要是把一些基础的概念搞清楚,基础打好了后面才容易理解。
What is DNS
DNS(Domain Name System),是互联网的一项服务。它的本质是一个KV存储的分布式数据库,key是域名,value是IP地址,其作用就是通过域名查询对应的IP地址。
DNS Detail
分层分级
需要理解DNS的工作原理,首先要理解域名的结构。先来看一个例子,以www.google.com
为例,实际上这里有四级域名,根域名是.
,顶级域名是com
,接下来是google.com
,最后是www.google.com
。这种设计的好处是,整个DNS数据可以存储成树的形式,这种查询会非常高效。比如我查询com
,那么我就不需要查询edu
或者gov
下的域名(至于为什么com
、edu
和gov
是并列关系,下文会解释),这就加快了查询的速度。
分层分级的关系大致可以理解为以下这张图:
可以看出,最上面是根域名,第二层是顶级域名,包括了com
和edu
,下面的google.com
就是三级域名以此类推。这种架构查询的高效性体现在,一旦我查询的顶级域名是com
,那么我就不需要去找其他顶级域名下的子域名。
分布式存储
上面通过介绍域名的构成已经分层分级的特点,相信大家对查询DNS有了一个基本的概念。然而分层分级是逻辑设计上的,与此不同的是实际存储上的分布式架构。
全球有非常多的域名,而且这些域名和IP地址之间的关系更新非常频繁,出于稳定性和可用性的要求,几乎不可能把所有的信息都存储在一台机器上。因此需要用一个分布式的存储架构去实现DNS的信息存储。
分布式存储实际上是利用了DNS分层分级的特点,思想是每一层的服务器只管理自己下一层的域名,不跨级管理。举个例子,根域名服务器只管理顶级域名,至于二级域名的管理则委派给各个顶级域服务器。所以如果你想申请顶级域名,你要去找根域名服务器;如果你想申请二级域名,你要去找顶级域名服务器。
绝大多数的情况下,我们都是想顶级域名服务器申请二级域名,如申请一个testdns.cn
的域名,那我只需要向cn
这个域名注册中心申请即可,申请完之后,testdns.cn
这个二级域名下的所有域名就归我管理,比如mail.testdns.cn
、www.testdns.cn
这些域名的DNS解析,就都是我管理了。
那么问题又来了,我怎么去管理属于我名下的域名呢?第一种方法是利用顶级域提供的nameserver来进行解析,我可以把每个子域名对应的IP地址配置上去,相当于利用公共的资源去管理;第二种方法就是我自己搭建一个testdns.cn
的nameserver,当别人请求到这个域名时,顶级域的服务器会返回我自己指定的nameserver的IP地址,然后别人再通过我自建的nameserver进一步查询这个域名下的子域名。一般情况下,都不需要自建nameserver,因为代价高而且麻烦,像我这种如果只是想弄一个个性化的域名给自己的博客之类的,完全没有必要自建nameserver。但某些情况除外:
- 对内DNS。组织内部如果有许多微服务需要通过域名来相互访问的话,完全没有必要每次都走外网去请求DNS解析,所以在内部搭建一个nameserver就很有必要;
- 性能问题。顶级域名注册商的nameserver大家都在用,性能必然是没这么好。如果对于性能和稳定性有极高要求,而且公司本身也是财大气粗的话,就完全可以自己搭建nameserver去提升服务质量。
DNS解析流程
上面讲述了DNS在服务器端的一些结构和存储方式,从服务器视角看DNS解析的请求是怎么样的。下面这里我将从调用方的视角来看看一个完整的DNS解析是怎么样的。
- 应用程序(例如是浏览器)拿到域名
www.google.com
后,去本地的DNS缓存查一下,看看是否有解析过的记录,如果有则直接返回(此时会标记为是非权威服务器的应答),如果没有继续下一步; - 有一个叫ISPDNS服务器,也叫递归解析服务器,它负责递归解析域名并最终返回一个该域名指向的IP地址。本地将会请求这个服务器,然后它会从配置文件中读取13个根域名服务器的地址(这13个根服务器的地址是不会改变并且持久化在本地的配置文件),然后向其中一台发起请求,请求的是
com
这个域名在哪个服务器; - 根服务器收到请求后,知道客户端要的是
com
的域名服务器,然后就会返回com
域中的NS记录; - 然后客户端拿到了
com
域的服务器地址,再去请求,此时请求的是google.com
的IP地址。 - 负责
com
域的顶级域名服务器收到请求后,返回google.com
的NS记录; - 继续递归第4、5步,直到拿到
www.google.com
的IP地址,然后就可以直接去访问了,同时把这个记录缓存下来,下一次再次解析的时候就不需要再去DNS解析了。
这个过程其实非常好理解,是通过分级加缓存的方式提高查询效率,每次都往更高一级的服务器请求它下一级的服务器信息。再通过缓存提高命中率,减少重复的查询。
智能解析
在实践中我们经常会遇到DNS解析的问题,其中很大部分就是DNS解析的时间过长。如果了解了上面的解析过程就可以知道其实整条链路很长,中间很多环节都是网络请求,其中的速度自然很难保证。同时还有一个很大的问题就是跨运营商的网络带宽。如果客户端是电信的用户,然后DNS解析返回的IP是联通的IP,那么这个请求将会耗时很长,所以为了解决这种问题,只能解析应运而生。
智能解析是基于一个域名对应多个IP的情况,如果使用智能解析,则会返回离用户最近的IP地址,这样用户访问速度会大大增加。智能解析的协议是EDNS,主要是在DNS包中添加了origin client IP,这样nameserver就会返回距离client IP比较近的server IP了。
DNS解析相关的命令
linux中有一些常用的DNS解析命令。如nslookup
、dig
等。