清风涛 發表於 2021-2-19 15:01:00

HTTP - 5. 域名

<h3 id="域名的出现">域名的出现</h3>
<p><strong>IP 协议的职责是“网际互连”,它在 MAC 层之上,使用 IP 地址把 MAC 编号转换成了四位数字,这就对物理网卡的 MAC 地址做了一层抽象。</strong><br>
例如,分为 <strong>A、B、C、D、E 五种类型</strong>,公有地址和私有地址,掩码分割子网等。<strong>只要每个小网络在 IP 地址这个概念上达成一致,不管它在 MAC 层有多大的差异,都可以接入 TCP/IP 协议栈,最终汇合进整个互联网。</strong>但接入互联网的计算机越来越多,IP 地址的缺点也就暴露出来了,最主要的是它“对人不友好”,虽然比 MAC 的 16 进制数要好一点,但还是<strong>难于记忆和输入。</strong><br>
解决办法:<br>
在 IP 地址之上再来一次抽象,把数字形式的 IP 地址转换成更有意义更好记的名字,在字符串的层面上再增加“新玩法”。于是,<strong>DNS 域名系统</strong>就这么出现了。</p>
<h3 id="域名的形式">域名的形式</h3>
<ul>
<li><strong>域名是一个有层次的结构,是一串用“.”分隔的多个单词,最右边的被称为“顶级域名”,然后是“二级域名”,层级关系向左依次降低。</strong></li>
<li><strong>最左边的是主机名,通常用来表明主机的用途</strong>,比如“www”表示提供万维网服务、“mail”表示提供邮件服务,不过这也不是绝对的,名字的关键是要让我们容易记忆。</li>
<li><code>www.baidu.com</code>
<ul>
<li>这里的“com”就是顶级域名,“baidu”是二级域名,“www”则是主机名。使用这个域名,DNS 就会把它转换成相应的 IP 地址,就可以访问该网站了。</li>
</ul>
</li>
<li>域名不仅能够代替 IP 地址,还有许多其他的用途。
<ul>
<li>在 Apache、Nginx 这样的 Web 服务器里,<strong>域名可以用来标识虚拟主机,决定由哪个虚拟主机来对外提供服务。</strong></li>
<li><strong>域名本质上还是个名字空间系统,使用多级域名就可以划分出不同的国家、地区、组织、公司、部门,每个域名都是独一无二的,可以作为一种身份的标识。</strong></li>
<li>因为这个特性,<strong>域名也被扩展到了其他应用领域</strong>,比如 <strong>Java 的包机制就采用域名作为命名空间</strong>,只是它使用了<strong>反序</strong>。如果极客时间要开发 Java 应用,那么它的包名可能就是“org.geekbang.time”。</li>
<li>而 XML 里使用 URI 作为名字空间,也是间接使用了域名。</li>
</ul>
</li>
</ul>
<h3 id="域名的解析">域名的解析</h3>
<p><strong>就像IP 地址必须转换成 MAC 地址才能访问主机一样,域名也必须要转换成 IP 地址,这个过程就是“域名解析”。</strong><br>
目前全世界有几亿个站点,有几十亿网民,而每天网络上发生的 HTTP 流量更是天文数字。<strong>这些请求绝大多数都是基于域名来访问网站的,所以 DNS 就成了互联网的重要基础设施,必须要保证域名解析稳定可靠、快速高效。</strong></p>
<ul>
<li>DNS 的核心系统是一个<strong>三层的树状、分布式服务</strong>,基本对应域名的结构:
<ul>
<li><strong>根域名服务器</strong>(Root DNS Server)
<ul>
<li>管理顶级域名服务器,返回“com”“net”“cn”等顶级域名服务器的 IP 地址;</li>
</ul>
</li>
<li><strong>顶级域名服务器</strong>(Top-level DNS Server)
<ul>
<li>管理各自域名下的权威域名服务器,比如 com 顶级域名服务器可以返回 apple.com 域名服务器的 IP 地址;</li>
</ul>
</li>
<li><strong>权威域名服务器</strong>(Authoritative DNS Server)
<ul>
<li>管理自己域名下主机的 IP 地址,比如 apple.com 权威域名服务器可以返回 www.apple.com 的 IP 地址。<br>
<img src="https://github.com/llliyufeng/http-note/blob/main/pic/DNS%E7%B3%BB%E7%BB%9F%E7%BB%93%E6%9E%84.png?raw=true" alt="DNS 的核心系统" loading="lazy"></li>
</ul>
</li>
</ul>
</li>
<li>在这里根域名服务器是关键,它必须是众所周知的,否则下面的各级服务器就无从谈起了。目前全世界共有 13 组根域名服务器,又有数百台的镜像,保证一定能够被访问到。</li>
<li>有了这个系统以后,任何一个域名都可以在这个树形结构里从顶至下进行查询,就好像是把域名从右到左顺序走了一遍,<strong>最终就获得了域名对应的 IP 地址。</strong></li>
<li>例如,要访问“www.apple.com”,就要进行下面的三次查询:
<ul>
<li>访问根域名服务器,它会告诉“com”顶级域名服务器的地址;</li>
<li>访问“com”顶级域名服务器,它再告诉“apple.com”域名服务器的地址;</li>
<li>最后访问“apple.com”域名服务器,就得到了“www.apple.com”的地址。</li>
</ul>
</li>
</ul>
<h3 id="减轻域名解析的方法">减轻域名解析的方法</h3>
<h4 id="缓存">缓存</h4>
<ul>
<li>虽然核心的 DNS 系统遍布全球,服务能力很强也很稳定,但如果全世界的网民都往这个系统里挤,即使不挤瘫痪了,访问速度也会很慢。所以<strong>在核心 DNS 系统之外,还有两种手段用来减轻域名解析的压力,并且能够更快地获取结果,基本思路就是“缓存”。</strong>
<ul>
<li>许多大公司、网络运行商都会建立自己的 DNS 服务器,作为用户 DNS 查询的代理,<strong>代替用户访问核心 DNS 系统。</strong>这些“野生”服务器被称为“<strong>非权威域名服务器</strong>”,<strong>可以缓存之前的查询结果,如果已经有了记录,就无需再向根服务器发起查询,直接返回对应的 IP 地址。</strong></li>
<li>这些 DNS 服务器的数量要比核心系统的服务器<strong>多很多</strong>,而且大多部署在离用户很近的地方。比较知名的 DNS 有 Google 的“8.8.8.8”,Microsoft 的“4.2.2.1”,还有 CloudFlare 的“1.1.1.1”等等。</li>
</ul>
</li>
<li>其次,<strong>操作系统里也会对 DNS 解析结果做缓存</strong>,如果你之前访问过“www.apple.com”,那么下一次在浏览器里再输入这个网址的时候就不会再跑到 DNS 那里去问了,<strong>直接在操作系统里就可以拿到 IP 地址</strong>。</li>
<li>另外,<strong>操作系统里还有一个特殊的“主机映射”文件</strong>,通常是一个可编辑的文本,在 Linux 里是“/etc/hosts”,在 Windows 里是“C:\WINDOWS\system32\drivers\etc\hosts”,<strong>如果操作系统在缓存里找不到 DNS 记录,就会找这个文件。</strong></li>
<li>有了上面的“野生”DNS 服务器、操作系统缓存和 hosts 文件后,很多域名解析的工作就都不用“跋山涉水”了,直接在本地或本机就能解决,不仅方便了用户,也减轻了各级 DNS 服务器的压力,效率就大大提升了。<br>
<img src="https://github.com/llliyufeng/http-note/blob/main/pic/DNS%E6%9E%B6%E6%9E%84.png?raw=true" alt="DNS架构" loading="lazy"></li>
</ul>
<h3 id="域名的新玩法">域名的“新玩法”</h3>
<h4 id="重定向">重定向</h4>
<p><strong>因为域名代替了 IP 地址,所以可以让对外服务的域名不变,而主机的 IP 地址任意变动。当主机有情况需要下线、迁移时,可以更改 DNS 记录,让域名指向其他的机器。</strong><br>
比如,有一台“buy.tv”的服务器要临时停机维护,那就可以通知 DNS 服务器:“这个 buy.tv 域名的地址变了,原先是 1.2.3.4,现在是 5.6.7.8,麻烦改一下。”<strong>DNS 于是就修改内部的 IP 地址映射关系</strong>,之后再有访问 buy.tv 的请求就不走 1.2.3.4 这台主机,改由 5.6.7.8 来处理,<strong>这样就可以保证业务服务不中断。</strong></p>
<h4 id="搭建一个在内部使用的-dns">搭建一个在内部使用的 DNS</h4>
<p>因为域名是一个名字空间,所以可以使用 bind9 等开源软件搭建一个在内部使用的 DNS,作为名字服务器。这样开发的各种内部服务就都用域名来标记,比如数据库服务都用域名“mysql.inner.app”,商品服务都用“goods.inner.app”,发起网络通信时也就不必再使用写死的 IP 地址了,可以直接用域名,而且这种方式也兼具了第一种“玩法”的优势。</p>
<h4 id="基于域名实现的负载均衡">基于域名实现的负载均衡</h4>
<ul>
<li>第一种方式,因为域名解析可以返回多个 IP 地址,所以一个域名可以对应多台主机,客户端收到多个 IP 地址后,就可以自己使用轮询算法依次向服务器发起请求,实现负载均衡。</li>
<li>第二种方式,域名解析可以配置内部的策略,返回离客户端最近的主机,或者返回当前服务质量最好的主机,这样在 DNS 端把请求分发到不同的服务器,实现负载均衡。</li>
</ul>
<p>前面说的都是可信的 DNS,如果有一些不怀好意的 DNS,那么它也可以在域名这方面“做手脚”,弄一些比较“恶意”的“玩法”,举两个例子:</p>
<ul>
<li>“域名屏蔽”,对域名直接不解析,返回错误,让你无法拿到 IP 地址,也就无法访问网站;</li>
<li>“域名劫持”,也叫“域名污染”,你要访问 A 网站,但 DNS 给了你 B 网站。</li>
</ul>
<p>网友总结:<br>
`</p>
<p>比如你有一个网站要上线,你在域名注册商那里申请了abc.com,那么你的域名A记录就保存在这个域名注册商的DNS服务器上,<strong>该DNS服务器称为权威域名服务器。</strong>当客户端访问abc.com时,<strong>先查找浏览器DNS缓存,没有则查找操作系统DNS缓存</strong>,在这一阶段是操<strong>作系统dnscache clinet 服务进行DNS缓存的</strong>(你在任务管理器里面可以看到一个dns客户端进程,就是这玩意实现缓存的),如果<strong>还是没有则查找hosts文件中的域名记录</strong>。然后依<strong>然没有的话则访问电脑上设置的DNS服务器IP(</strong>根据本地网卡被分配的 dns server ip 来进行解析,dns server ip 一般是“非官方”的ip<strong>),比如三大营运商的dns服务器或者谷歌的8.8.8.8,</strong>此时这一层的DNS服务器称为“<strong>野生DNS缓存服务器</strong>”,也就是非权威域名服务器。如果<strong>还是没有则非权威域名服务器会去查找 根域名服务器-顶级域名服务器-二级域名服务器-权威域名服务器</strong> ,这样客户端就在权威域名服务器上找到了abc.com对应的IP了,这个IP可以是多个,每次客户端请求的时候域名服务器会根据<strong>负载均衡算法</strong>分配一个IP给你。<strong>当DNS缓存失效了,则重新开始新一轮的域名请求。</strong><br>
总结如下:<br>
<strong>浏览器缓存-&gt;操作系统dnscache -&gt;hosts文件-&gt;非权威域名服务器-&gt;根域名服务器-&gt;顶级域名服务器-&gt;二级域名服务器-&gt;权威域名服务器。</strong><br>
其中非权威域名服务器还包括LDNS(企业内网DNS服务器),三大营运商DNS,谷歌公开的DNS,微软公开的DNS等。<br>
另外DNS请求有两种方式:<strong>递归查询和迭代查询</strong>,这方面大家可以网上了解一下。LDNS往后面查询一般是递归查询,因为公司内网是有防火墙的,全部请求通过LDNS来递归查询然后把结果给内网用户。</p>
<p>`</p>
<blockquote>
<p>http-note 笔记内容来自极客时间《透视HTTP协议》专栏--罗剑锋老师 努力学习 受益匪浅</p>
</blockquote><br><br>
来源:https://www.cnblogs.com/liyf-98/p/14416168.html
頁: [1]
查看完整版本: HTTP - 5. 域名