You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
10 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 06 | 域名里有哪些门道?
在上一讲里我们学习了HTTP协议使用的TCP/IP协议栈知道了HTTP协议是运行在TCP/IP上的。
IP协议的职责是“网际互连”它在MAC层之上使用IP地址把MAC编号转换成了四位数字这就对物理网卡的MAC地址做了一层抽象发展出了许多的“新玩法”。
例如分为A、B、C、D、E五种类型公有地址和私有地址掩码分割子网等。只要每个小网络在IP地址这个概念上达成一致不管它在MAC层有多大的差异都可以接入TCP/IP协议栈最终汇合进整个互联网。
但接入互联网的计算机越来越多IP地址的缺点也就暴露出来了最主要的是它“对人不友好”虽然比MAC的16进制数要好一点但还是难于记忆和输入。
怎么解决这个问题呢?
那就“以其人之道还治其人之身”在IP地址之上再来一次抽象把数字形式的IP地址转换成更有意义更好记的名字在字符串的层面上再增加“新玩法”。于是DNS域名系统就这么出现了。
## 域名的形式
在第4讲曾经说过域名是一个有层次的结构是一串用“.”分隔的多个单词,最右边的被称为“顶级域名”,然后是“二级域名”,层级关系向左依次降低。
最左边的是主机名通常用来表明主机的用途比如“www”表示提供万维网服务、“mail”表示提供邮件服务不过这也不是绝对的名字的关键是要让我们容易记忆。
看一下极客时间的域名“time.geekbang.org”这里的“org”就是顶级域名“geekbang”是二级域名“time”则是主机名。使用这个域名DNS就会把它转换成相应的IP地址你就可以访问极客时间的网站了。
域名不仅能够代替IP地址还有许多其他的用途。
在Apache、Nginx这样的Web服务器里域名可以用来标识虚拟主机决定由哪个虚拟主机来对外提供服务比如在Nginx里就会使用“server\_name”指令
```
server {
listen 80; #监听80端口
server_name time.geekbang.org; #主机名是time.geekbang.org
...
}
```
域名本质上还是个名字空间系统,使用多级域名就可以划分出不同的国家、地区、组织、公司、部门,每个域名都是独一无二的,可以作为一种身份的标识。
举个例子吧假设A公司里有个小明B公司里有个小强于是他们就可以分别说是“小明.A公司”“小强.B公司”即使B公司里也有个小明也不怕可以标记为“小明.B公司”很好地解决了重名问题。
因为这个特性域名也被扩展到了其他应用领域比如Java的包机制就采用域名作为命名空间只是它使用了反序。如果极客时间要开发Java应用那么它的包名可能就是“org.geekbang.time”。
而XML里使用URI作为名字空间也是间接使用了域名。
## 域名的解析
就像IP地址必须转换成MAC地址才能访问主机一样域名也必须要转换成IP地址这个过程就是“**域名解析**”。
目前全世界有几亿个站点有几十亿网民而每天网络上发生的HTTP流量更是天文数字。这些请求绝大多数都是基于域名来访问网站的所以DNS就成了互联网的重要基础设施必须要保证域名解析稳定可靠、快速高效。
DNS的核心系统是一个三层的树状、分布式服务基本对应域名的结构
1. 根域名服务器Root DNS Server管理顶级域名服务器返回“com”“net”“cn”等顶级域名服务器的IP地址
2. 顶级域名服务器Top-level DNS Server管理各自域名下的权威域名服务器比如com顶级域名服务器可以返回apple.com域名服务器的IP地址
3. 权威域名服务器Authoritative DNS Server管理自己域名下主机的IP地址比如apple.com权威域名服务器可以返回www.apple.com的IP地址。
![](https://static001.geekbang.org/resource/image/6b/f2/6b020454987543efdd1cf6ddec784bf2.png)
在这里根域名服务器是关键它必须是众所周知的否则下面的各级服务器就无从谈起了。目前全世界共有13组根域名服务器又有数百台的镜像保证一定能够被访问到。
有了这个系统以后任何一个域名都可以在这个树形结构里从顶至下进行查询就好像是把域名从右到左顺序走了一遍最终就获得了域名对应的IP地址。
例如你要访问“www.apple.com”就要进行下面的三次查询
1. 访问根域名服务器它会告诉你“com”顶级域名服务器的地址
2. 访问“com”顶级域名服务器它再告诉你“apple.com”域名服务器的地址
3. 最后访问“apple.com”域名服务器就得到了“www.apple.com”的地址。
虽然核心的DNS系统遍布全球服务能力很强也很稳定但如果全世界的网民都往这个系统里挤即使不挤瘫痪了访问速度也会很慢。
所以在核心DNS系统之外还有两种手段用来减轻域名解析的压力并且能够更快地获取结果基本思路就是“**缓存**”。
首先许多大公司、网络运行商都会建立自己的DNS服务器作为用户DNS查询的代理代替用户访问核心DNS系统。这些“野生”服务器被称为“非权威域名服务器”可以缓存之前的查询结果如果已经有了记录就无需再向根服务器发起查询直接返回对应的IP地址。
这些DNS服务器的数量要比核心系统的服务器多很多而且大多部署在离用户很近的地方。比较知名的DNS有Google的“8.8.8.8”Microsoft的“4.2.2.1”还有CloudFlare的“1.1.1.1”等等。
其次操作系统里也会对DNS解析结果做缓存如果你之前访问过“www.apple.com”那么下一次在浏览器里再输入这个网址的时候就不会再跑到DNS那里去问了直接在操作系统里就可以拿到IP地址。
另外操作系统里还有一个特殊的“主机映射”文件通常是一个可编辑的文本在Linux里是“/etc/hosts”在Windows里是“C:\\WINDOWS\\system32\\drivers\\etc\\hosts”如果操作系统在缓存里找不到DNS记录就会找这个文件。
有了上面的“野生”DNS服务器、操作系统缓存和hosts文件后很多域名解析的工作就都不用“跋山涉水”了直接在本地或本机就能解决不仅方便了用户也减轻了各级DNS服务器的压力效率就大大提升了。
下面的这张图比较完整地表示了现在的DNS架构。
![](https://static001.geekbang.org/resource/image/e5/ac/e51df3245609880641043af65bba94ac.png)
在Nginx里有这么一条配置指令“resolver”它就是用来配置DNS服务器的如果没有它那么Nginx就无法查询域名对应的IP也就无法反向代理到外部的网站。
```
resolver 8.8.8.8 valid=30s; #指定Google的DNS缓存30秒
```
## 域名的“新玩法”
有了域名又有了可以稳定工作的解析系统于是我们就可以实现比IP地址更多的“新玩法”了。
第一种也是最简单的“重定向”。因为域名代替了IP地址所以可以让对外服务的域名不变而主机的IP地址任意变动。当主机有情况需要下线、迁移时可以更改DNS记录让域名指向其他的机器。
比如你有一台“buy.tv”的服务器要临时停机维护那你就可以通知DNS服务器“我这个buy.tv域名的地址变了啊原先是1.2.3.4现在是5.6.7.8麻烦你改一下。”DNS于是就修改内部的IP地址映射关系之后再有访问buy.tv的请求就不走1.2.3.4这台主机改由5.6.7.8来处理,这样就可以保证业务服务不中断。
第二种因为域名是一个名字空间所以可以使用bind9等开源软件搭建一个在内部使用的DNS作为名字服务器。这样我们开发的各种内部服务就都用域名来标记比如数据库服务都用域名“mysql.inner.app”商品服务都用“goods.inner.app”发起网络通信时也就不必再使用写死的IP地址了可以直接用域名而且这种方式也兼具了第一种“玩法”的优势。
第三种“玩法”包含了前两种,也就是基于域名实现的负载均衡。
这种“玩法”也有两种方式,两种方式可以混用。
第一种方式因为域名解析可以返回多个IP地址所以一个域名可以对应多台主机客户端收到多个IP地址后就可以自己使用轮询算法依次向服务器发起请求实现负载均衡。
第二种方式域名解析可以配置内部的策略返回离客户端最近的主机或者返回当前服务质量最好的主机这样在DNS端把请求分发到不同的服务器实现负载均衡。
前面我们说的都是可信的DNS如果有一些不怀好意的DNS那么它也可以在域名这方面“做手脚”弄一些比较“恶意”的“玩法”举两个例子
* “域名屏蔽”对域名直接不解析返回错误让你无法拿到IP地址也就无法访问网站
* “域名劫持”也叫“域名污染”你要访问A网站但DNS给了你B网站。
好在互联网上还是好人多而且DNS又是互联网的基础设施这些“恶意DNS”并不多见你上网的时候不需要太过担心。
## 小结
这次我们学习了与HTTP协议有重要关系的域名和DNS在这里简单小结一下今天的内容
1. 域名使用字符串来代替IP地址方便用户记忆本质上一个名字空间系统
2. DNS就像是我们现实世界里的电话本、查号台统管着互联网世界里的所有网站是一个“超级大管家”
3. DNS是一个树状的分布式查询系统但为了提高查询效率外围有多级的缓存
4. 使用DNS可以实现基于域名的负载均衡既可以在内网也可以在外网。
## 课下作业
1. 在浏览器地址栏里随便输入一个不存在的域名比如就叫“www.不存在.com”试着解释一下它的DNS解析过程。
2. 如果因为某些原因DNS失效或者出错了会出现什么后果
欢迎你把自己的答案写在留言区,与我和其他同学一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
![unpreview](https://static001.geekbang.org/resource/image/78/36/7838e0e705864ddfeacc79e0aeb8f236.png)