最初在网上看到这个问题时,似乎是某个人面试时被问到的问题。这个问题倒是个很开放性的问题,自己稍微想了下,也略微搜索了下网上的一些相关文章,感觉这样一个简单的日常上网动作,后面涉及到了如此多的技术点。如果能够通过这样一个简单的案例,把各个知识点串一遍,在各个知识点之间建立联系,对记忆这些知识很有帮助,大脑里也能形成一种系统性的知识结构。
一、DNS域名解析
首先,我们得在浏览器里输入一个网址,就拿taobao做例子 吧。
输入后按下回车,这时候浏览器会首先进行域名解析。所谓域名解析,就是将我们输入的www.taobao.com这个url解析成浏览器实际访问时使用的ip地址。这个解析的过程就要利用到DNS协议了。简单的说,浏览器会到DNS服务器上进行域名的查找,但实际上的过程远比这个复杂,后面再说。而浏览器和DNS服务器之间的通信则使用的是DNS协议。
DNS协议的报文有两种:
- 查询报文
- 应答报文
如下图所示,就是执行www.taobao.com域名查询的报文
这里对查询报文的具体格式就不深究了。只单独说下图中最下方二进制数据中蓝色高亮的部分。这部分记录了请求的URL文本,其编码格式是对URL中按点号分段后得到多段,每段前加上对该段的字符长度计数值,最终拼接成一串。例如图中的具体含义是:
03 77 77 77 = 3 + www
06 74 61 6f 62 61 6f = 6 + taobao
03 63 6f 6d = 3 + com
对应的应答报文如下图,它与查询报文的格式是很相似的。
二、关于DNS的各种八卦
DNS的结构
就我目前了解到的知识来看,DNS系统的结构有下面3个最大的特点
- 分布式
- 树状
- 授权解释
所谓分布式,实际上是指整个DNS系统是由多个服务器共同组成的一个分布式系统,具体的每个域名信息分散在系统中的各个服务器上。
而树状则是指这些服务器之间是一个典型的树层次结构联系起来的。这里盗个图
如上图所示,域名本身按层次进行了划分。而这些域名会由一到多个DNS服务器记录其相关信息,这样看,对于www.taobao.com这个域名,com的部分有一些服务器进行管理,taobao这个由另一些来管理,www的又由其他的管理。其中,处于树顶端的是根服务器,根服务器主要用来管理互联网的主目录,全世界只有13台,1个为主根服务器,放置在美国。其余12个均为辅根服务器,其中9个放置在美国,欧洲2个,位于英国和瑞典,亚洲1个,位于日本。
这样对于一个域名的查询,实际会涉及到多个DNS服务器。而在具体的查询中,常常提到两个概念:递归查询、迭代查询。网上对这两个概念的说法似乎各有各的理解,这里也谈谈我了解到。
- 对于递归查询,就是说当客户端(例如浏览器)向DNS服务器发起查询时,如果这个DNS服务器不知道答案,就会向其他DNS服务器进行查询,直到查到结果或超时。这样DNS服务器就相当于一个跑腿的,在帮客户端代理执行到其他DNS服务器的查询工作。具体举个例子,当我想查找www.taobao.com的IP地址时,我会向我机器上配置的DNS服务器首先发起询问(我机器的DNS如下图所示)
浏览器:211.137.130.3啊,告诉我www.taobao.com的IP。
211.137.130.3:我也不知道,我帮你问问
211.137.130.3:根服务器啊,www.taobao.com的IP是啥?
根服务器:我不知道,问问com那边吧,到xxx机器去问
211.137.130.3:com啊,www.taobao.com的IP是啥?
com:我不知道,问问taobao那边吧,到yyy机器去问
211.137.130.3:taobao啊,www.taobao.com的IP是啥?
taobao:我不知道,问问www那边吧,到zzz机器去问
211.137.130.3:www啊,www.taobao.com的IP是啥?
www:是这个,拿去吧
211.137.130.3:嘿,浏览器,帮你问到了哈,搞定
- 对于迭代查询,查询的过程类似,只是变成由客户端自己来跑腿了,而不是由DNS服务器代理。
而上面这个查询过程,也反映了DNS结构的另一个特点,就是授权解释。实际上可以看到,一个域名的解释是由一个具有权威性的DNS服务器来做最正统的回答,其他服务器不知道的情况下都会向他获取权威答案。这里涉及到DNS中的两个概念:
- SOA(Start of Authority)
该记录表明DNS域名服务器是DNS域中的数据表的信息来源,该服务器是主机名字的管理者 - NS(Name Server)
该记录是域名服务器记录,用来指定该域名由哪个DNS服务器来进行解析
也就是说,通过SOA可以确定哪个服务器是解析域名的权威,而通过NS可以找到这个权威服务器。
另外值得一提的是,前面提到多次查询过程实际中不会每次、频繁的发生,因为每个服务器都将这些查询结果做了缓存,减少向其他服务器查询的次数,以提高效率。
作为全局负载均衡
大型web应用常常要使用负载均衡来满足用户对使用服务的效率需求。这种负载均衡可以在各个层面上应用,例如数据库层面的负载均衡、web服务器的负载均衡等等。
而DNS也可以作为一种全局的负载均衡手段来提高应用的性能。从原理上说,就是在DNS服务器上,为同一个域名配置多个不同的IP地址,这样用户在查询IP地址时就会获得其中一个IP进行访问,这样就起到了分流的作用。
即用TCP,也用UDP
DNS协议是一个比较另类的应用层协议,它即使用了TCP协议,也使用了UDP协议,端口都是53。在查询时优先选择UDP,区域数据传输必须采用TCP。
一些DNS相关命令
- dig
www:~ leo$ dig @a.gtld-servers.net github.com
; <<>> DiG 9.8.3-P1 <<>> @a.gtld-servers.net github.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61943
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 6
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;github.com. IN A
;; AUTHORITY SECTION:
github.com. 172800 IN NS ns1.p16.dynect.net.
github.com. 172800 IN NS ns3.p16.dynect.net.
github.com. 172800 IN NS ns2.p16.dynect.net.
github.com. 172800 IN NS ns4.p16.dynect.net.
github.com. 172800 IN NS ns-520.awsdns-01.net.
github.com. 172800 IN NS ns-421.awsdns-52.com.
github.com. 172800 IN NS ns-1707.awsdns-21.co.uk.
github.com. 172800 IN NS ns-1283.awsdns-32.org.
;; ADDITIONAL SECTION:
ns1.p16.dynect.net. 172800 IN A 208.78.70.16
ns3.p16.dynect.net. 172800 IN A 208.78.71.16
ns2.p16.dynect.net. 172800 IN A 204.13.250.16
ns4.p16.dynect.net. 172800 IN A 204.13.251.16
ns-520.awsdns-01.net. 172800 IN A 205.251.194.8
ns-421.awsdns-52.com. 172800 IN A 205.251.193.165
;; Query time: 392 msec
;; SERVER: 192.5.6.30#53(192.5.6.30)
;; WHEN: Sat Jul 15 18:10:46 2017
;; MSG SIZE rcvd: 344
www:~ leo$
如上例所示,是使用dig命令,向a.gtld-serers.net这个DNS服务器查询github.com得到的返回结果(注意在DNS服务器前面要加上@符号)。可以在其中的AUTHORITY SECTION中看到,一共返回了8个SOA的DNS服务器。如果继续向其中几个查询,可以得到下面的一些结果。
例如,访问ns1.p16.dynect.net,在ANSWER SECTION得到github.com的两个IP:192.30.255.113、192.30.255.112。这也就是前面说的使用DNS做负载均衡的一个案例。
www:~ leo$ dig @ns1.p16.dynect.net github.com
; <<>> DiG 9.8.3-P1 <<>> @ns1.p16.dynect.net github.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5267
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 8, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;github.com. IN A
;; ANSWER SECTION:
github.com. 60 IN A 192.30.255.113
github.com. 60 IN A 192.30.255.112
;; AUTHORITY SECTION:
github.com. 900 IN NS ns4.p16.dynect.net.
github.com. 900 IN NS ns-1707.awsdns-21.co.uk.
github.com. 900 IN NS ns3.p16.dynect.net.
github.com. 900 IN NS ns-421.awsdns-52.com.
github.com. 900 IN NS ns1.p16.dynect.net.
github.com. 900 IN NS ns-520.awsdns-01.net.
github.com. 900 IN NS ns2.p16.dynect.net.
github.com. 900 IN NS ns-1283.awsdns-32.org.
;; Query time: 573 msec
;; SERVER: 208.78.70.16#53(208.78.70.16)
;; WHEN: Sat Jul 15 18:17:20 2017
;; MSG SIZE rcvd: 280
www:~ leo$
- nslookup
该命令也可以返回一个域名的IP地址,如下所示
www:~ leo$ nslookup
> www.jd.com
Server: 211.137.130.3
Address: 211.137.130.3#53
Non-authoritative answer:
www.jd.com canonical name = www.jdcdn.com.
Name: www.jdcdn.com
Address: 111.20.253.129
>
有时如果在浏览器中访问一个网址发现不能成功,可以用这个命令试一下域名解析是否正确。如果这里正确,那有时可能是电脑的DNS缓存由问题导致的,可以尝试清除本地缓存。
三、各种缓存
之前说到,在浏览器进行域名解析时,会向DNS服务器进行查询。然而实际情况并非怎么简单直接。为了提高效率,这个过程中有各种分处各个层次的缓存来加速这个过程。这里copy一段来自http://blog.jobbole.com/33951/ 的文字:
- 浏览器缓存 – 浏览器会缓存DNS记录一段时间。 有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。
- 系统缓存 – 如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname)。这样便可获得系统缓存中的记录。
- 路由器缓存 – 接着,前面的查询请求发向路由器,它一般会有自己的DNS缓存。
- ISP DNS 缓存 – 接下来要check的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。
- 递归搜索 – 你的ISP的DNS服务器从根域名服务器开始进行递归搜索,从.com顶级域名服务器到Facebook的域名服务器。一般DNS服务器的缓存中会有.com域名服务器中的域名,所以到顶级服务器的匹配过程不是那么必要了。
后记
关于DNS的知识还是很庞大复杂的,后面有机会再进一步学习了解吧。
另外,追加个链接:http://www.cnblogs.com/ityouknow/p/6380603.html
大致说的是一家p2p金融公司由于人员离职的交接工作没做到位,导致公司买的DNS服务欠费,使得有的用户无法访问公司网站,结果有些用户以为公司准备跑路,到处散播恐慌消息。给公司带来不小影响。看过后即觉得挺好笑的,也深深觉得要保证做好一个业务,真的是一点马虎不得啊。
参考
http://blog.csdn.net/jiangsd198/article/details/60780187
https://segmentfault.com/a/1190000002578457