为什么要有DNS

如果咱们想要拜访某度,你能够在浏览器上的搜寻栏里输出112.80.248.76这个IP地址,中转页面。

这样的行为,非法,但有病

大部分人,连本人对象的电话号码都记不住,又怎么可能记得住这么一串IP地址呢。

哦,不好意思,挫伤到兄弟们了,你们没对象。

但我假如你们有。

回忆一下,尽管你记不住对象的电话号码,但却不影响你给她打电话。你的操作过程是不是关上通讯录,输出"富婆",而后就弹出一个电话号码。点击即拨打。

在计算机领域,你大概率也记不住IP,所以也须要有相似的通讯录的性能。比方,你只须要输出www.baidu.com,它就能帮你找到对应的 112.80.248.76,而后进行拜访。

其中www.baidu.com 是域名,通过这个域名能够取得它背地的IP是112.80.248.76

就像一个人能够有多个电话号码一样,一个域名也能够对应有多个IP地址。

而将域名解析为IP的过程,也就是查"通讯录"的过程,其实就是DNSDomain Name System,域名零碎)协定须要做的事件。

另外须要留神的是,下面的这个IP地址,我写这篇文章的时候能拜访,不代表大家看文章的时候能拜访。因为这背地的IP地址是有可能变更的。能够通过应用 ping www.baidu.com取得最新的IP地址。

但问题就来了。

普通人的通讯录,个别有一千个电话号码就算是社交小达人了,放在通讯录里入不敷出。

然而网站域名,却不一样,据说2015年的时候就曾经超过3亿了。

如果将这3亿条记录都放在一个服务器里,会有两个问题

  • • 超过3亿条域名数据,数据量过大,并且数据量继续减少
  • • 须要接受大量的读申请。每个网站域名都可能会有成千的拜访。这加起来,四舍五入也有千亿qps了。

显然,如果将DNS做成相似手机通讯录这样的单点服务,那是不可能实现这样的能力的,必须得是分布式系统

于是,问题就变成了,如何设计一个反对千亿+qps申请的大型分布式系统

我晓得必定有人要说:"这是服务只有10qps的人该思考的事件吗?"

尽管咱们做的服务可能只有10qps,但这并不障碍咱们学习DNS里优良的设计。

咱们就从URL的层次结构聊起。

URL的层次结构

举个例子。一个常见的域名,比方 www.baidu.com

能够看到,这个域名两头用了两个句点。通过句点符号,能够将域名分为三局部。

其中com被称为一级域顶级域,其余常见的顶级域还有cn,co等,baidu二级域www则是三级域

除此之后,在com前面,其实还有一个被省略掉的句点号。它叫根域

当域名多起来了之后,将它们雷同的局部抽取进去,多个域名就能够变成这样的树状层级构造

这时候咱们就能够看到,这些域之间其实是一种层级关系,就像是学校,年级,班级那样。

当你想要去定位一个具体域名的时候,你就能够通过这样的层级找到对应的域名。

举个例子。大家应该还记得那句广告词,"三年级2班的李小明同学,你妈妈拿了两罐旺仔牛奶给你",其实李小明的妈妈,就是通过,学校、年级、班级的层级模式,一层层找到人。

DNS的原理

咱们从新回来看下大佬们是怎么设计DNS。

先间接说最重要的论断。

  • • 利用层级构造去拆分服务
  • • 退出多级缓存

接下来开展。

利用URL层级构造去拆分服务

DNS承载的流量压力十分大,必须要做成分布式服务,于是问题的要害就变成了如何拆分服务

既然URL是树状的层级构造,那保留它们的服务,也能够根据这个,十分天然的拆成树状的模式。

一台服务器保护一个或多个域的信息。于是服务就变成了上面这样的层级模式。

当咱们须要拜访www.baidu.com

查问过程就跟下图一样。

申请会先打到最近的DNS服务器(比方你家的家用路由器)中,如果在DNS服务器中找不到,则DNS服务器会间接询问根域服务器,在根域服务器中尽管没有www.baidu.com这条记录的,但它能够晓得这个URL属于com域,于是就找到com域服务器的IP地址,而后拜访com域服务器,反复下面的操作,再找到放了baidu域的服务器是哪个,持续往下,直到找到www.baidu.com的那条记录,最初返回对应的IP地址

能够看到,原理比较简单,但这里波及到两个问题。

  • • 本机怎么晓得最近的DNS服务器IP是什么?
  • • 最近的DNS服务器怎么晓得根域的IP是多少?

咱们一个个来答复。

本机怎么晓得最近的DNS服务器的IP是什么?

这个在之前写过的《刚插上网线,电脑怎么晓得本人的IP是什么?》 提到过,插上网线时,机子会通过DHCP协定取得本机的IP地址,子网掩码,路由器地址,以及DNS服务器的IP地址

上面是我的mac机子,第二阶段DHCP Offer中的抓包截图。能够看到,这外面返回的信息里蕴含了DNS服务器的IP

同时也能够在左上角的点左上角的苹果图标->零碎表偏好设置->网络->高级->DNS中查看到DNS服务器的IP地址。

这里有个小细节,从下面的抓包图里能够看到路由器地址和DNS服务器地址,以及DHCP服务器地址,其实都是192.168.31.1,这个其实是我这边的家用路由器的IP地址,也就是说个别家用路由器自带这几个性能。

而在某里云服务器里,DNS服务器也是一样,是通过dhcp协定取得。查看DNS服务器的IP地址也很不便,执行cat /etc/resolv.conf就好了。

这下面的nameserver中,能够看出有两台DNS服务器,机子会依照文件中呈现的程序来发动申请,如果第一台服务器没反馈,就会去申请第二台。

最近的DNS服务器怎么晓得根域的IP是多少?

咱们也晓得根域,就是域名树的顶层,既然是顶层,那信息个别也就绝对少一些。对应的IPV4地址只有13个,IPV6地址只有25个。

咱们能够通过dig命令的+trace选项来查看一个域名的dns解析过程。

而后面提到的传说中的13个根域,从字母a-m,就都在上图中。

但这又引发了一个问题,下面看到的都是域名。

这。。。

"我原本是想通过域名去找IP的,你又让我去找其余域名的IP?"

听起来不迷信,这不就死循环了吗。

是的,所以这些根域名对应的IP会以配置文件的模式,放在每个域名服务器中。

也就是说并不需要再去申请根域名对应的IP,间接在配置里能读出来就好了。

上面这个截图是域名服务器里的配置内容。

能够看到A结尾的根域,它的IPV4地址是198.41.0.4

退出多级缓存

对于高并发读多写少的场景,退出缓存简直就是标配。

DNS也不例外,它加了缓存,而且不止一层。

从在浏览器的搜寻框中输出URL。它会先后拜访浏览器缓存操作系统的缓存/etc/hosts最近的DNS服务器缓存。如果都找不到,才是到根域,顶级(一级)域,二级域等DNS服务器进行查问申请。

于是申请过程就成了下图这样。能够看到下面提到的好几有缓存的中央我都加了个绿色的小文件图标,优先在缓存里做查问。

因为缓存了下面树状构造的信息,最近的DNS服务器也不再须要每次都从根域开始查起。比方在缓存里能找到baidu.com的服务器IP,就间接跳到二级域服务器上做查找就好了。

正因为多级缓存的存在,每一层理论接管到的申请都大大减少了。并且每个人日常拜访的网站也就那么几个,所以大部分时候都能命中缓存间接返回IP地址。

简略小结下。

DNS的设计中,通过层次结构将服务进行拆分,流量扩散到多个服务器中。

又通过退出多级缓存,让每个层级理论接管到的申请大大减少,因而大大提高了零碎的性能。

两点,是咱们做业务开发的过程中能够参考的优良设计。

还有一点,是咱们大概率学不来的,叫任播,它也为DNS实现高并发解决能力提供了重要反对,我会把它放到放到下一篇文章开展聊聊。

协定格局

DNS是个域名解析零碎,而运行在这套零碎上的协定,就叫DNS协定

和HTTP相似,DNS协定也是个应用层协定

下图是它的报文格式。

字段太多,很晕?这就对了。

咱们就挑几个重点的说说。

Transsaction ID是事务ID,对于一次申请和这个申请对应的应答,他们的事务ID是一样的,相似于微服务零碎中的log_id

flag字段是指标记位,有2个Byte,16个bit,须要关注的是QROpCodeRCode

  • • QR用来标记这是个查问还是响应报文,0是查问,1是响应。
  • • OpCode用来标记操作码,失常查问都是0,不论是域名查ip,还是ip查域名,都属于失常查问。能够粗犷的认为咱们平时只会看到0
  • • RCode是响应码,相似于HTTP里的404, 502 这样的status code。用来示意这次申请的后果是否失常。0是指一切正常。1是指报文格式谬误,2服务域名服务器外部谬误。

Queries字段,是指你理论查问的内容。这里其实蕴含三局部信息,NameTypeClass

  • • Name能够放域名或者IP。比方你要查的是baidu.com这个域名对应的IP,那外面放的就是域名,反过来通过IP查对应的域名,那Name字段里放的就是IP
  • • Type是指你想查哪种信息,比方你想查这个域名对应的IP地址是什么,那就是填A(address),如果你想查这个域名有没有其余别名,就填CNAME(Canonical Name)。如果你想查 xiaobaidebug@gmail.com对应的邮箱服务器地址是什么(比方 gmail.com),那就填MX(Mail Exchanger)。除此之外还有很多类型,上面是常见的Type表格。

  • • Class字段就比拟有意思了,你能够简略的认为,咱们只会看到它填IN (Internet)。其实DNS协定原本设计进去是思考到可能会有更多的利用场景的,比方这里还能填CHHS。大家甚至都不须要晓得它们是什么含意,因为随着工夫的倒退,这些都曾经成化石了,咱们晓得这个字段的惟一作用,可能就是能够在面试的时候能够随便装个x,深藏功与名。

Answers字段,从名字能够看出,跟Queries对应,一问一答。作用是返回查问后果,比方通过域名查对应的IP地址,这个字段里就会放入具体的IP信息。

抓包

原理看完了,来抓个包吧。

咱们关上wireshark。而后执行

dig www.baidu.com

此时操作系统会收回DNS申请,查问 www.baidu.com对应的IP地址。

下面的图里是DNS查问(request)的内容,能够看到它是应用层的协定,传输层用的是UDP协定进行数据传输。截图里标红的局部,也就是下面提到的须要重点关注的报文字段内容。其中flag字段是按bit展现的,因而抓包里进行了分行展现。

接下来再看下响应(response)的数据包内容。

能够看到事务ID(Transaction ID)跟DNS申请报文是统一的。并且Answers字段里带有两个IP地址。试了下,两个IP地址都是能够失常拜访的。

总结

  • DNS是十分优良的高并发分布式系统,通过层次结构将服务进行拆分,流量扩散到多个服务器中。又通过退出多级缓存,让每个层级理论接管到的缓存大大减小,因而大大提高了零碎的性能。这两点在做业务开发的过程中是能够借鉴的。
  • 插上网线通网时,本机通过DHCP协定取得DNS服务器的地址。
  • 根域服务器的IP会以配置的模式加载到每一台DNS服务器当中。因而拜访任意一台DNS服务器都能轻松找到根域对应的IP地址。

最初

最初给大家留下两个问题。

  • 从抓包能够看出,DNS在传输层上应用了UDP协定,那它只用UDP吗?
  • 下面提到,DNS的IPV4根域名只有13个,这外面其实有不少都部署在丑陋国,那是不是意味着,只有他们不快乐了,切断咱们的拜访,咱们的网络就得瘫痪了呢?