程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

面试题:浏览器输入URL之后会发生什么? —— DNS协议

发布于2021-05-30 20:06     阅读(577)     评论(0)     点赞(22)     收藏(3)


写在前面
博主在字节一面的时候,面试官就问我:浏览器输入URL之后,会发生什么?
虽然博主心里知道面试官想考察的内容是对网络包传输的流程,但是当时还是答得不是很好,故决定总结一系列文章来好好讲讲网络相关知识。
此为系列第一讲,讲的内容是关于DNS协议的。

博主当时的回答

博主当时的回答是这样的
当用户输入一个URL之后,浏览器会根据HTTP/HTTPS协议将该请求逐个经过TCP/IP协议栈进行封装。在应用层除了根据HTTP/HTTPS协议添加报头之外,还会根据DNS协议去查询URL所对应的服务器,获取该服务器的IP地址。然后将该IP添加到网络包的目的IP中。之后和服务器建立TCP三次握手,之后服务器响应浏览器的请求,讲请求包发给浏览器。客户端收到请求包之后会根据请求包内的内容将资源渲染给用户。之后,如果是短链接,会进行TCP四次挥手;如果是长链接,则双方会建立相关信息维护这条链接。

今天的文章就是去讲DNS协议在这个过程中扮演了什么样的角色。

DNS服务器

在网络世界中,IP地址是唯一标识主机的DNS。但是我们在www.baidu.com其实也可以访问百度的主机啊?这是因为有DNS服务器这个网络世界的地址簿。它记录了域名和IP地址的对应关系。由于现实世界中域名的大量使用,所以DNS服务器就一定要设置成高可用、高并发和分布式的

于是,就有了以下的树状层次结构:
在这里插入图片描述

域名和DNS解析

域名本身我们都很熟悉,其是一串用点分割开的字符串。其本身是全球唯一的,需要通过专门的域名注册商才可以申请注册。为了组织全球互联网中的众多计算机,域名的一个个块被用点分开,形成分层的结构。而每个被点分开的字符串就构成了域名中的一个层级,并且位置越靠后,层级就越高。

我们拿CSDN的网址:www.csdn.net来看一下,这个字符串中,.net是顶级域名,中间的.csdn是二级域名。这里有一点要注意以下,.是所有域名的根,也就是说所有域名都以点作为后缀。比如说www.csdn.net,其实最后会被修饰成www.csdn.net.

DNS解析流程

为了提高DNS的解析效率,很多网络都会就近部署DNS缓存服务器。于是就有了以下的DNS解析流程:

  1. 主机客户端现在本地DNS缓存中查询数据,如果没有就转到第二步。
  2. 然后本地域名服务器(本地DNS)询问www.csdn.net的ip地址是多少?本地DNS就是由网络服务商,电信、移动、联通等自动分配,它通常是在网络服务商的某个机房。
  3. 本地DNS收到客户端的请求之后,会去它缓存的域名-IP对应表中查询www.csdn.net所对应的IP地址。如果找到了就返回给客户端;如果没找到就将此请求转发到根DNS服务器
  4. 根DNS服务器收到请求之后,发现后缀是.net,就将.net顶级域名服务器的地址给客户端发过去。
  5. 客户端收到地址后,就去.net顶级域名服务器上去请求。顶级域名服务器负责管理二级域名。
  6. .net顶级域名服务器收到请求之后,就将负责www.csdn.net区域的权威DNS服务器地址给客户端。
  7. 客户端收到权威DNS服务器的地址后,就去权威DNS服务器上请求IP地址,权威DNS服务器将IP返回给客户端
  8. 收到IP地址之后,客户端就可以根据IP地址访问目标服务器了

在这里插入图片描述

查看本地DNS配置

上面的DNS递归查询挺麻烦的,不过其是DNS服务器自动完成。我们要做的就是配置可用的DNS服务器。

我们可以在Linux中输入以下命令来查看我们的系统配置:

ubuntu@VM-0-2-ubuntu:~/code/Code/leetcode$ cat /etc/resolv.conf 
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "systemd-resolve --status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0

在这里,博主的系统配置的是127.0.0.53这个域名服务器。

查看域名对应的IP地址

另外,DNS服务通过资源记录的方式,来管理所有数据,其支持A、CNAME、MX、NS、PTR等多种类型的记录。比如:

  • A:把域名转换成IP地址
  • CNAME:创建别名
  • NS:该域名对应的域名服务器地址

我们可以在Linux中使用 nslookup 运行以下命令查看域名的A记录:

ubuntu@VM-0-2-ubuntu:~/code/Code/leetcode$ nslookup www.csdn.net
# 域名服务器及端口信息
Server:         127.0.0.53
Address:        127.0.0.53#53

# 非权威查询结果
Non-authoritative answer:
Name:   www.csdn.net
Address: 39.106.226.142

在这上面我们最终在本地DNS缓存中查询到了www.csdn.net的IP地址,是39.106.226.142

查看DNS递归过程

前面DNS查询流程的时候,还提到了。如果没有命中缓存,DNS查询实际上是一个递归的过程

那么我们如何去查看DNS这个递归的过程呢?在Linux中我们可以使用解析工具 dig,其就提供了trace功能,可以展示递归查询的整个过程。

ubuntu@VM-0-2-ubuntu:~/code/Code/leetcode$ dig +trace +nodnssec www.csdn.com
; <<>> DiG 9.11.3-1ubuntu1.13-Ubuntu <<>> +trace +nodnssec www.csdn.com
;; global options: +cmd
;; Received 28 bytes from 127.0.0.53#53(127.0.0.53) in 0 ms

博主,这里就是在本地DNS缓存中查找到了www.csdn.com的IP地址。

DNS负载均衡

我们现在回到DNS解析流程那里,站在客户端的角度,这是一次DNS递归查询的过程。因为本地DNS会全权完成这件事情。而我们只需要等待结果罢了。但是,在这个过程中,DNS除了可以通过名称映射为IP地址,它还可以做另一件事情,就是负载均衡

例如,某个应用要访问另外一个应用,如果配置另外一个应用的IP地址,那么这个访问就是一对一的。但是当被访问的应用撑不住的时候,我们其实可以部署多个。这样在域名解析的时候,我们只要配置策略,这次返回第一个IP,下次返回第二个IP,这样就可以实现负载均衡了

一般来说,大型的架构服务需要保证高可用。为了保证高可用,我们往往会将服务部署在多个机房,每个机房都会有自己的IP地址。当用户访问某个域名的时候,这个IP地址就可以轮询访问多个数据中。如果一个数据中心因为某种原有挂了之后,只要在DNS服务器里面。将这个数据中心对应的IP地址删除,就可以实现一定的高可用。

参考文献

[1] 刘超.趣谈网络协议.极客时间
[2] 倪朋飞.Linux性能优化实战.极客时间

原文链接:https://blog.csdn.net/shenmingxueIT/article/details/117389594



所属网站分类: 技术文章 > 博客

作者:龙膜授权

链接:http://www.phpheidong.com/blog/article/86741/48525f74593448b6ca0b/

来源:php黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

22 0
收藏该文
已收藏

评论内容:(最多支持255个字符)