尽人事,听天命。博主东南大学研究生在读,热爱健身和篮球,正在为两年后的秋招准备中,乐于分享技术相关的所见所得,关注公众号 @ 飞天小牛肉,第一时间获取文章更新,成长的路上我们一起进步
本文已收录于 CS-Wiki(Gitee 官方推荐项目,现已 0.9k star),致力打造完善的后端知识体系,在技术的路上少走弯路,欢迎各位小伙伴前来交流学习
0. 前言
为了保证网址的正常访问,域名解析协议(DNS)其实在背后做出了很多努力,本文将透彻讲解 DNS 协议的原理,了解我们每天都在接触的网址到底是怎么工作的。
1. 什么是 DNS 协议
在学习 DNS 协议之前,我们先区分一下域名和 IP 地址这个两个概念:
- IP 地址:一长串能够唯一地标记网络上的计算机的数字
- 域名:又称网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时对计算机的定位标识(有时也指地理位置)比如
www.baidu.com
不知道有没有同学会混淆域名和网址的概念,可以这样理解,网址里面含有域名。举个例子:
www.gitee.com/veal98
就是一个网址,而www.gitee.com
就是域名
由于 IP 地址具有不方便记忆并且不能显示地址组织的名称和性质等缺点,人们设计出了域名,并通过域名解析协议(DNS,Domain Name System)来将域名和 IP 地址相互映射,使人更方便地访问互联网,而不用去记住能够被机器直接读取的 IP 地址数串。将域名映射成 IP 地址称为正向解析,将 IP 地址映射成域名称为反向解析。
DNS 协议可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。但大多数情况下 DNS 都使用 UDP 进行传输。
2. 域名详解
那么域名由谁来规定和管理呢?不能是随便写吧?
全世界域名的最高管理机构,是一个叫做 ICANN (Internet Corporation for Assigned Names and Numbers)的组织,总部在美国加州。ICANN 负责管理全世界域名系统的运作。
域名其实是具有一定的层次结构的,从上到下依次为:根域名、顶级域名(top level domain,TLD)、二级域名、(三级域名)
① 顶级域名
先来讲讲顶级域名(TLD),即最高层级的域名。简单说,就是网址的最后一个部分。比如,网址www.baidu.com
的顶级域名就是 .com
。ICANN 的一项主要工作,就是规定哪些字符串可以当作顶级域名。截至 2015 年 7 月,顶级域名共有 1058 个,它们大致可以分成两类:
- 一类是通用顶级域名(gTLD),比如
.com
、.net
、.edu
、.org
、.xxx
等等,共有 700 多个。 - 另一类是国家顶级域名(ccTLD),代表不同的国家和地区,比如
.cn
(中国)、.io
(英属印度洋领地)、.cc
( 科科斯群岛)、.tv
(图瓦卢)等,共有 300 多个。
当然,ICANN 自己不会去管理这些顶级域名,因为根本管不过来。想想看,顶级域名有1000多个,每个顶级域名下面都有许多批发商,如果每个都要管,就太麻烦了。ICANN 的政策是,每个顶级域名都找一个托管商,该域名的所有事项都由托管商负责。ICANN 只与托管商联系,这样管理起来就容易多了。举例来说,.cn
国家顶级域名的托管商就是中国互联网络信息中心(CNNIC),它决定了 .cn
域名的各种政策。
② 二级域名
而二级域名(Second Level Domain,SLD) 在通用顶级域名或国家顶级域名之下具有不同的意义:
- 通用顶级域名下的二级域名:一般是指域名注册人选择使用的网上名称,如
yahoo.com
(商业组织通常使用自己的商标、商号或其他商业标志作为自己的网上名称,如baidu.com
) - 国家顶级域名下的二级域名:一般是指类似于通用顶级域名的表示注册人类别和功能的标志。例如,在
.com.cn
域名结构中,.com
此时是置于国家顶级域名.cn
下的二级域名,表示中国的商业性组织,以此类推。
三级域名是形如 www.baidu.com
的域名,可以当做是二级域名的子域名,特征为域名包含两个 .
。对于域名所有者/使用者而言,三级域名都是二级域名的附属物而无需单独费用。三级域名甚至不能称为域名,一般称之为域名下的 “二级目录”。
③ 根域名
那么根域名在哪里呢?在层次结构中根域名不是最顶级的吗?域名中怎么没有看见它?
由于 ICANN 管理着所有的顶级域名,所以它是最高一级的域名节点,被称为根域名(root domain)。在有些场合,www.xxx.com
被写成 www.xxx.com.
,即最后还会多出一个点。这个点就是根域名。
理论上,所有域名的查询都必须先查询根域名,因为只有根域名才能告诉你,某个顶级域名由哪台服务器管理。事实上也确实如此,ICANN 维护着一张列表(根域名列表),里面记载着顶级域名和对应的托管商。
比如,我要访问abc.xyz
,也必须先去询问根域名列表,它会告诉我 .xyz
域名由 CentralNic 公司托管。根域名列表还记载,.google
由谷歌公司托管,.apple
由苹果公司托管等等。
由于根域名列表很少变化,大多数 DNS 服务商都会提供它的缓存,所以根域名的查询事实上不是那么频繁。
3. 域名服务器详解
域名服务器是指管理域名的主机和相应的软件,它可以管理所在分层的域的相关信息。一个域名服务器所负责管里的分层叫作 区 (ZONE)。域名的每层都设有一个域名服务器:
- 根域名服务器
- 顶级域名服务器
- 权限域名服务器
下面这幅图就很直观了:
除了上面三种 DNS 服务器,还有一种不在 DNS 层次结构之中,但是很重要的 DNS 服务器,即本地域名服务器。下面我们分别讲解这四种服务器都是用来干什么的
① 根域名服务器
上面我们提到,ICANN 维护着一张根域名列表,里面记载着顶级域名和对应的托管商,其实根域名列表的正式名称是 DNS 根区(DNS root zone),保存 DNS 根区文件的服务器,就叫做 DNS 根域名服务器(root name server)。根域名服务器保存所有的顶级域名服务器的地址
由于早期的 DNS 查询结果是一个 512 字节的 UDP 数据包。这个包最多可以容纳 13 个服务器的地址,因此就规定全世界有 13 个根域名服务器,编号从 a.root-servers.net
一直到 m.root-servers.net
。其中 10 台设置在美国,另外各有一台设置于荷兰、瑞典和日本。
前面我们说过,理论上所有域名的查询都必须先查询根域名,所以一般来说所有的域名服务器都会注册一份根域名服务器的 IP 地址的缓存,用于在必要的时候向其发送请求。
② 顶级域名服务器
按照根域名服务器管理顶级域名的逻辑,顶级域名服务器显然就是用来管理注册在该顶级域名下的所有二级域名的,记录这些二级域名的 IP 地址。
③ 权限域名服务器
按照上面的逻辑,权限域名服务器应该是管理注册在二级域名下的所有三/四级域名的,但其实不是这样,如果一个二级域名或者一个三/四级域名对应一个域名服务器,则域名服务器数量会很多,我们需要使用划分区的办法来解决这个问题。那么权限域名服务器就是负责管理一个“区”的域名服务器。
什么是区?怎样划分区呢?
区和域其实是不同的,区可以有多种不同的划分方法。以百度为例,我们假设有 fanyi.baidu.com
、ai.baidu.com
、tieba.baidu.com
这三个三级域名。我们可以这样分区,fanyi.baidu.com
和 tieba.baidu.com
放在 baidu.com
权限域名服务器,ai.baidu.com
放在 ai.baidu.com
权限域名服务器中。并且 baidu.com
权限域名服务器和 ai.baidu.com
权限域名服务器是同等地位的,而具体怎么分区是百度公司根据域名多少、访问多少等情况去自己规定的。
画个图直观理解一下:
④ 本地域名服务器
除了上面三种 DNS 服务器,还有一种不在 DNS 层次结构之中,但是很重要的 DNS 服务器,就是本地域名服务器(也被称为权威域名服务器)。本地域名服务器是电脑解析时的默认域名服务器,即电脑中设置的首选 DNS 服务器和备选 DNS 服务器。常见的有电信、联通、谷歌、阿里等的本地 DNS 服务。
每个因特网服务提供者或一所大学,甚至一所大学中的各个系,都可以拥有一个本地域名服务器。当一台主机发出 DNS 查询请求时,这个查询请求报文就发送给该主机的本地域名服务器。本地域名服务器管理本地域名的解析和映射,并且能够向上级域名服务器进行查询。
那么具体本地域名服务器是如何向上级域名服务器转发查询请求的呢?
4. DNS 查询方式
具体 DNS 查询的方式有两种:
- 递归查询
- 迭代查询
所谓迭代就是,如果请求的接收者不知道所请求的内容,那么接收者将扮演请求者,发出有关请求,直到获得所需要的内容,然后将内容返回给最初的请求者。
通俗点来说,在递归查询中,如果 A 请求 B,那么 B 作为请求的接收者一定要给 A 想要的答案;而迭代查询则是指,如果接收者 B 没有请求者 A 所需要的准确内容,接收者 B 将告诉请求者 A,如何去获得这个内容,但是自己并不去发出请求。
一般来说,域名服务器之间的查询使用迭代查询方式,以免根域名服务器的压力过大。通过下面这两个图就能很好的理解了
1)递归查询:
2)迭代查询:
5. 域名缓存
上面讲解的是域名服务器之间的 DNS 查询请求过程,但实际上,每个时刻都有无数网民要上网,那每次都去访问本地域名服务器去获取 IP 地址显然是不实际的。解决方法就是使用缓存保存域名和 IP 地址的映射。
计算机中 DNS 记录在本地有两种缓存方式:浏览器缓存和操作系统缓存。
1)浏览器缓存:浏览器在获取网站域名的实际 IP 地址后会对其进行缓存,减少网络请求的损耗。每种浏览器都有一个固定的 DNS 缓存时间,如 Chrome 的过期时间是 1 分钟,在这个期限内不会重新请求 DNS
2)操作系统缓存:操作系统的缓存其实是用户自己配置的 hosts 文件。比如 Windows10 下的 hosts 文件存放在 C:\Windows\System32\drivers\etc\hosts
Windows 系统默认开启 DNS 缓存服务,服务名是 DNSClient
,可以缓存一些常用的域名。
使用命令 ipconfig/displaydns
可以查看电脑中缓存的域名。
⭐ 在浏览器中进行访问的时候,会优先查询浏览器缓存,如果未命中则继续查询操作系统缓存,最后再查询本地域名服务器,然后本地域名服务器会递归的查找域名记录,最后返回结果。主机和本地域名服务器之间的查询方式是递归查询,也就是说主机请求本地域名服务器,那么本地域名服务器作为请求的接收者一定要给主机想要的答案。
6. 完整域名解析过程
OK,将我们上面所说的域名服务器之间的 DNS 查询请求过程和域名缓存结合起来,就是一个完整的 DNS 协议进行域名解析的过程。这里我们以正向解析为例(域名解析成 IP 地址):
1)首先搜索浏览器的 DNS 缓存,缓存中维护一张域名与 IP 地址的对应表;
2)若没有命中,则继续搜索操作系统的 DNS 缓存;
3)若仍然没有命中,则操作系统将域名发送至本地域名服务器,本地域名服务器查询自己的 DNS 缓存,查找成功则返回结果(注意:主机和本地域名服务器之间的查询方式是递归查询);
4)若本地域名服务器的 DNS 缓存没有命中,则本地域名服务器向上级域名服务器进行查询,通过以下方式进行迭代查询(注意:本地域名服务器和其他域名服务器之间的查询方式是迭代查询,防止根域名服务器压力过大):
- 首先本地域名服务器向根域名服务器发起请求,根域名服务器是最高层次的,它并不会直接指明这个域名对应的 IP 地址,而是返回顶级域名服务器的地址,也就是说给本地域名服务器指明一条道路,让他去这里寻找答案
- 本地域名服务器拿到这个顶级域名服务器的地址后,就向其发起请求,获取权限域名服务器的地址
- 本地域名服务器根据权限域名服务器的地址向其发起请求,最终得到该域名对应的 IP 地址
4)本地域名服务器将得到的 IP 地址返回给操作系统,同时自己将 IP 地址缓存起来
5)操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来
6)至此,浏览器就得到了域名对应的 IP 地址,并将 IP 地址缓存起来
配合下图直观理解:
关注公众号 | 飞天小牛肉,即时获取更新
- 博主东南大学研究生在读,利用课余时间运营一个公众号『 飞天小牛肉 』,2020/12/29 日第一次开通,专注分享计算机基础(数据结构 + 算法 + 计算机网络 + 数据库 + 操作系统 + Linux)、Java 基础和面试指南的相关原创技术好文。本公众号的目的就是让大家可以快速掌握重点知识,有的放矢。希望大家多多支持哦,和小牛肉一起成长
- 并推荐个人维护的开源教程类项目: CS-Wiki(Gitee 推荐项目,现已 0.9k star), 致力打造完善的后端知识体系,在技术的路上少走弯路,欢迎各位小伙伴前来交流学习 ~