1.4 DNS域名解析
我们知道互联网都是通过URL来发布和请求资源的,而URL中的域名需要解析成IP地址才能与远程主机建立连接,如何将域名解析成IP地址就属于DNS解析的工作范畴。
可以毫不夸张地说,虽然我们平时上网感觉不到DNS解析的存在,但是一旦DNS解析出错,可能会导致非常严重的互联网灾难。目前世界上的整个互联网有几个DNS根域名服务器,任何一台根服务器坏掉后果都会非常严重。
1.4.1 DNS域名解析过程
图1-10是DNS域名解析的主要请求过程实例图。
图1-10 DNS域名解析
如图1-10所示,当一个用户在浏览器中输入www.abc.com时,DNS解析将会有将近10个步骤,这个过程大体描述如下。
当用户在浏览器中输入域名并按下回车键后,第1步,浏览器会检查缓存中有没有这个域名对应的解析过的IP地址,如果缓存中有,这个解析过程就将结束。浏览器缓存域名也是有限制的,不仅浏览器缓存大小有限制,而且缓存的时间也有限制,通常情况下为几分钟到几小时不等,域名被缓存的时间限制可以通过TTL属性来设置。这个缓存时间太长和太短都不好,如果缓存时间太长,一旦域名被解析到的IP有变化,会导致被客户端缓存的域名无法解析到变化后的IP地址,以致该域名不能正常解析,这段时间内有可能会有一部分用户无法访问网站。如果时间设置太短,会导致用户每次访问网站都要重新解析一次域名。
第2步,如果用户的浏览器缓存中没有,浏览器会查找操作系统缓存中是否有这个域名对应的DNS解析结果。其实操作系统也会有一个域名解析的过程,在Windows中可以通过C:\Windows\System32\drivers\etc\hosts文件来设置,你可以将任何域名解析到任何能够访问的IP地址。如果你在这里指定了一个域名对应的IP地址,那么浏览器会首先使用这个IP地址。例如,我们在测试时可以将一个域名解析到一台测试服务器上,这样不用修改任何代码就能测试到单独服务器上的代码的业务逻辑是否正确。正是因为有这种本地DNS解析的规程,所以黑客就有可能通过修改你的域名解析来把特定的域名解析到它指定的IP地址上,导致这些域名被劫持。
这导致早期的Windows版本中出现过很严重的问题,而且对于一般没有太多电脑知识的用户来说,出现问题后很难发现,即使发现也很难自己解决,所以Windows 7中将hosts文件设置成了只读的,防止这个文件被轻易修改。
在Linux中这个配置文件是/etc/named.conf,修改这个文件可以达到同样的目的,当解析到这个配置文件中的某个域名时,操作系统会在缓存中缓存这个解析结果,缓存的时间同样是受这个域名的失效时间和缓存的空间大小控制的。
前面这两个步骤都是在本机完成的,所以在图1-10中没有表示出来。到这里还没有涉及真正的域名解析服务器,如果在本机中仍然无法完成域名的解析,就会真正请求域名服务器来解析这个域名了。
第3步,如何、怎么知道域名服务器呢?在我们的网络配置中都会有“DNS服务器地址”这一项,这个地址就用于解决前面所说的如果两个过程无法解析时要怎么办,操作系统会把这个域名发送给这里设置的LDNS,也就是本地区的域名服务器。这个DNS通常都提供给你本地互联网接入的一个DNS解析服务,例如你是在学校接入互联网,那么你的DNS服务器肯定在你的学校,如果你是在一个小区接入互联网的,那这个DNS就是提供给你接入互联网的应用提供商,即电信或者联通,也就是通常所说的SPA,那么这个DNS通常也会在你所在城市的某个角落,通常不会很远。在Windows下可以通过ipconfig查询这个地址,如图1-11所示。
图1-11 在Windows中查询DNS Server
在Linux下可以通过如下方式查询配置的DNS Server,如图1-12所示。
图1-12 在Linux中下查询DNS Server
这个专门的域名解析服务器性能都会很好,它们一般都会缓存域名解析结果,当然缓存时间是受域名的失效时间控制的,一般缓存空间不是影响域名失效的主要因素。大约80%的域名解析都到这里就已经完成了,所以LDNS主要承担了域名的解析工作。
第4步,如果LDNS仍然没有命中,就直接到Root Server域名服务器请求解析。
第5步,根域名服务器返回给本地域名服务器一个所查询域的主域名服务器(gTLD Server)地址。gTLD是国际顶级域名服务器,如.com、.cn、.org等,全球只有13台左右。
第6步,本地域名服务器(Local DNS Server)再向上一步返回的gTLD服务器发送请求。
第7步,接受请求的gTLD服务器查找并返回此域名对应的Name Server域名服务器的地址,这个Name Server通常就是你注册的域名服务器,例如你在某个域名服务提供商申请的域名,那么这个域名解析任务就由这个域名提供商的服务器来完成。
第8步,Name Server域名服务器会查询存储的域名和IP的映射关系表,正常情况下都根据域名得到目标IP记录,连同一个TTL值返回给DNS Server域名服务器。
第9步,返回该域名对应的IP和TTL值,Local DNS Server会缓存这个域名和IP的对应关系,缓存的时间由TTL值控制。
第10步,把解析的结果返回给用户,用户根据TTL值缓存在本地系统缓存中,域名解析过程结束。
在实际的DNS解析过程中,可能还不止这10个步骤,如Name Server也可能有多级,或者有一个GTM来负载均衡控制,这都有可能会影响域名解析的过程。
1.4.2 跟踪域名解析过程
在Linux和Windows下都可以用nslookup命令来查询域名的解析结果,如图1-13所示。
图1-13 用nslookup查询域名解析结果
在Linux系统中还可以使用dig命名来查询DNS的解析过程,如下所示:
[junshan@v101055.sqa.cm4 admin]$ dig www.taobao.com ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5 <<>> www.taobao.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16903 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 3, ADDITIONAL: 3 ;; QUESTION SECTION: ;www.taobao.com. IN A ;; ANSWER SECTION: www.taobao.com. 1542 IN CNAME www.gslb.taobao.com. www.gslb.taobao.com. 130 IN A 115.238.23.251 www.gslb.taobao.com. 130 IN A 115.238.23.241 ;; AUTHORITY SECTION: gslb.taobao.com. 70371 IN NS gslbns3.taobao.com. gslb.taobao.com. 70371 IN NS gslbns1.taobao.com. gslb.taobao.com. 70371 IN NS gslbns2.taobao.com. ;; ADDITIONAL SECTION: gslbns1.taobao.com. 452 IN A 121.0.23.218 gslbns2.taobao.com. 452 IN A 115.124.17.70 gslbns3.taobao.com. 452 IN A 110.75.3.193 ;; Query time: 5 msec ;; SERVER: 10.232.2.254#53(10.232.2.254) ;; WHEN: Sun Feb 12 19:19:052012 ;; MSG SIZE rcvd: 201
结果的第1行输出了当前Linux的版本号,第2行说明可以增加可选参数printcmd,如果加上printcmd,打印出来的结果如下:
;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 58602 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;printcmd. IN A ;; AUTHORITY SECTION: . 10800 IN SOA a.root-servers.net. nstld. verisign-grs.com. 20120212001800900 60480086400 ;; Query time: 208 msec ;; SERVER: 10.232.2.254#53(10.232.2.254) ;; WHEN: Sun Feb 12 19:20:592012 ;; MSG SIZE rcvd: 101
“QUESTION SECTION”部分表示当前查询的域名是一个A记录,“ANSWER SECTION”部分返回了这个域名由CNAME到www.gslb.taobao.com,返回了这个域名对应的IP地址。
还可通过增加+trace参数跟踪这个域名的解析过程,如下所示:
[junshan@v101055.sqa.cm4 admin]$ dig www.taobao.com +trace ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5 <<>> www.taobao.com +trace ;; global options: printcmd . 449398 IN NS k.root-servers.net. . 449398 IN NS l.root-servers.net. . 449398 IN NS m.root-servers.net. . 449398 IN NS a.root-servers.net. . 449398 IN NS b.root-servers.net. . 449398 IN NS c.root-servers.net. . 449398 IN NS d.root-servers.net. . 449398 IN NS e.root-servers.net. . 449398 IN NS f.root-servers.net. . 449398 IN NS g.root-servers.net. . 449398 IN NS h.root-servers.net. . 449398 IN NS i.root-servers.net. . 449398 IN NS j.root-servers.net. ;; Received 272 bytes from 10.232.2.254#53(10.232.2.254) in 0 ms com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. com. 172800 IN NS m.gtld-servers.net. ;; Received 492 bytes from 193.0.14.129#53(k.root-servers.net) in 607 ms taobao.com. 172800 IN NS ns1.taobao.com. taobao.com. 172800 IN NS ns2.taobao.com. taobao.com. 172800 IN NS ns3.taobao.com. ;; Received 134 bytes from 192.5.6.30#53(a.gtld-servers.net) in 250 ms www.taobao.com. 1800 IN CNAME www.gslb.taobao.com. gslb.taobao.com. 86400 IN NS gslbns2.taobao.com. gslb.taobao.com. 86400 IN NS gslbns3.taobao.com. gslb.taobao.com. 86400 IN NS gslbns1.taobao.com. ;; Received 169 bytes from 110.75.1.19#53(ns1.taobao.com) in 0 ms
上面清楚地显示了整个域名是如何发起和解析的,从根域名(.)到gTLD Server(.com.)再到Name Server(taobao.com.)的整个过程都显示出来了。还可以看出DNS的服务器有多个备份,可以从任何一台查询到解析结果。
1.4.3 清除缓存的域名
我们知道DNS域名解析后会缓存解析结果,其中主要在两个地方缓存结果,一个是Local DNS Server,另外一个是用户的本地机器。这两个缓存都是TTL值和本机缓存大小控制的,但是最大缓存时间是TTL值,基本上Local DNS Server的缓存时间就是TTL控制的,很难人工介入,但是我们的本机缓存可以通过如下方式清除。
在Windows下可以在命令行模式下执行ipconfig /flushdns命令来刷新缓存,如图1-14所示。
图1-14 在Windows下刷新DNS缓存
在Linux下可以通过/etc/init.d/nscd restart来清除缓存,如图1-15所示。
图1-15 在Linux下清除DNS缓存
重启依然是解决很多问题的第一选择。
在Java应用中JVM也会缓存DNS的解析结果,这个缓存是在InetAddress类中完成的,而且这个缓存时间还比较特殊,它有两种缓存策略:一种是正确解析结果缓存,另一种是失败的解析结果缓存。这两个缓存时间由两个配置项控制,配置项是在 %JAVA_HOME%\lib\security\java.security文件中配置的。两个配置项分别是networkaddress.cache. ttl和networkaddress.cache.negative.ttl,它们的默认值分别是-1(永不失效)和10(缓存10秒)。
要修改这两个值同样有几种方式,分别是:直接修改java.security文件中的默认值、在Java的启动参数中增加-Dsun.net.inetaddr.ttl=xxx来修改默认值、通过InetAddress类动态修改。
在这里还要特别强调一下,如果我们需要用InetAddress类解析域名时,一定要是单例模式,不然会有严重的性能问题,如果每次都创建InetAddress实例,每次都要进行一次完整的域名解析,非常耗时,这点要特别注意。
1.4.4 几种域名解析方式
域名解析记录主要分为A记录、MX记录、CNAME记录、NS记录和TXT记录。
◎ A记录,A代表的是Address,用来指定域名对应的IP地址,如将item.taobao.com指定到115.238.23.241,将switch.taobao.com指定到121.14.24.241。A记录可以将多个域名解析到一个IP地址,但是不能将一个域名解析到多个IP地址。
◎ MX记录,表示的是Mail Exchange,就是可以将某个域名下的邮件服务器指向自己的,如taobao.com域名的A记录IP地址是115.238.25.245,如果MX记录设置为115.238.25.246,是xxx@taobao.com的邮件路由,DNS会将邮件发送到115.238.25.246所在的服务器,而正常通过Web请求的话仍然解析到A记录的IP地址。Mail Server
◎ CNAME记录,全称是Canonical Name(别名解析)。所谓的别名解析就是可以为一个域名设置一个或者多个别名。如将taobao.com解析到xulingbo.net,将srcfan.com也解析到xulingbo.net。其中xulingbo.net分别是taobao.com和srcfan.com的别名。前面的跟踪域名解析中的“www.taobao.com. 1542 IN CNAME www.gslb.taobao.com”就是CNAME解析。
◎ NS记录,为某个域名指定DNS解析服务器,也就是这个域名有指定的IP地址的DNS服务器去解析,前面的“gslb.taobao.com. 86400 IN NS gslbns2.taobao. com.”就是NS解析。
◎ TXT记录,为某个主机名或域名设置说明,如可以为xulingbo.net设置TXT记录为“君山的博客|许令波”这样的说明。