“从浏览器中输入URL到页面加载的发生了什么“,这是一道经典的面试题,涉及到的知识面非常多,但作为一个自认为对网络知识掌握的比较好的老码农来说,回答这个问题自然不在话下。如果这道题目如果在面试出现,对我来说就是送分题啊。尽管如此,我还是愿意花一些时间根据我自己的理解回答一下这个题目,看我自己到底掌握的有多深,同时也把自己的知识梳理一下。
这让我想起另外一件往事,这道题有点类似于“在手机上浏览器上输入一个URL,手机做了一些什么”,我当时学习通信里的核心网时就给自己提出过这个问题。
我非常愿意将这个面试题的答案共享出来,一是希望得到大家的意见,二是也希望对那些不是特别熟的人起到一些帮助。
因为文章较长,我将它们分为三大部份,后面会提供该文章的完整PDF版本,供大家下载。
正如前面所说,这篇文章涉及到的知识面非常丰富,我相信您绝对可以从本文里学到很多基础知识,还有一些高级话题。
自认为是目前写的最详细的一篇文章了,因为里面有理论,有实战,应该会起到一个比较好的效果。
总的来说,当你输入在浏览器里输入一个URL到页面加载,发生的顺序如下:
假设输入的URL是包含域名的,那肯定会涉及到DNS解析。当然,如果URL仅仅是IP,那就不会涉及到DNS的。域名的出现是为了方便记忆,因为域名比IP好记。我们这里假设URL包含域名。
解析的步骤大致如下图:
首先,在
本地域名服务器中根据域名查询IP地址,如果没有找到的情况下,本地域名服务器会向
根域名服务器发送一个请求。 如果根域名服务器也不存在该域名时,本地域名会向com
顶级域名服务器(TLD)发送一个请求,依次类推下去。 直到最后本地域名服务器得到google的IP地址并把它缓存到本地,供下次查询使用。 可以参考页面
https://www.verisign.com/en_US/website-presence/online/how-dns-works/index.xhtml ,该页面诠释了DNS的过程。 需要说明的是Root DNS Server一般有13个,后面有个点(.),别忘了。
a.root-servers.net.
c.root-servers.net.
j.root-servers.net.
b.root-servers.net.
i.root-servers.net.
d.root-servers.net.
k.root-servers.net.
f.root-servers.net.
l.root-servers.net.
h.root-servers.net.
m.root-servers.net.
g.root-servers.net.
e.root-servers.net.
这里的Capacity: 1000,代表缓存1K条,那么每条记录缓存多久呢?参看
timeout 1 这里的1代表1分钟。 如果是系统缓存,一般分2种情况: Linux 操作系统 见下图,一般在/etc/hosts下。
Windows操作系统 一般在 C:\Windows\System32\Drivers\etc\hosts。 谈到这里,我给大家 分享一个特别有用的技巧。 我们在做开发和测试时,会有一种情况,经常会去访问某个(测试)URL,例如 http://192.168.1.8:8080/admin/login, 如果这样的话,我们极有可能存在一个问题,觉得每次输入ip真的很麻烦。怎么解决?那么我们可以这么做,利用DNS的原理,将某个伪hostname(abc-test)加入到hosts里,只需加入一条记录: 192.168.1.8. abc-test 这样就可以用 http://abc-test:8080/admin/login去访问了,简单易用,对吧。
| 记录类型 | 含义简介 |
| A(Address) | 指定域名对应的IPv4地址 |
| AAAA | 指定域名对应的IPv6地址 |
| NS(Name Server) | 指定该域名由哪个DNS服务器来进行解析 |
| MX(Mail Exchanger) | 邮件交换记录,用于电子邮件系统发邮件时根据收信人的地址后缀来定位邮件服务器 |
| CNAME | 别名记录,多个域名映射到同一台计算机(如同一主机提供mail和www服务) |
| TXT | 主机名或域名的说明 |
| TTL(Time-To-Live) | DNS服务器中保存的时间 |
| PTR | 将一个主机地址映射到对应的域名 |
| HINFO | 说明映射到特定 DNS 主机名的 CPU 类型和操作系统类型 |
| [warren]$ dig ; <<>> DiG 9.9.5-3ubuntu0.16-Ubuntu <<>> ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57775 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;. IN NS ;; ANSWER SECTION: . 16265 IN NS a.root-servers.net. . 16265 IN NS c.root-servers.net. . 16265 IN NS j.root-servers.net. . 16265 IN NS b.root-servers.net. . 16265 IN NS i.root-servers.net. . 16265 IN NS d.root-servers.net. . 16265 IN NS k.root-servers.net. . 16265 IN NS f.root-servers.net. . 16265 IN NS l.root-servers.net. . 16265 IN NS h.root-servers.net. . 16265 IN NS m.root-servers.net. . 16265 IN NS g.root-servers.net. . 16265 IN NS e.root-servers.net. ;; Query time: 0 msec ;; SERVER: 208.113.157.202#53(208.113.157.202) ;; WHEN: Thu Nov 29 18:04:06 PST 2018 ;; MSG SIZE rcvd: 239 |
| dig www.jd.com ; <<>> DiG 9.10.6 <<>> www.jd.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2675 ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.jd.com. IN A ;; ANSWER SECTION: www.jd.com. 300 IN CNAME www.jd.com.gslb.qianxun.com. www.jd.com.gslb.qianxun.com. 300 IN CNAME www.jdcdn.com. www.jdcdn.com. 300 IN A 61.174.55.1 ;; Query time: 3 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Fri Nov 30 10:07:37 CST 2018 ;; MSG SIZE rcvd: 106 |
| nslookup www.jd.com Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: www.jd.com canonical name = www.jd.com.gslb.qianxun.com. www.jd.com.gslb.qianxun.com canonical name = www.jdcdn.com. Name: www.jdcdn.com Address: 61.174.55.1 |
请参看第89和90包,这是查询
www.jd.com 的request和response。 第89包细节图如下:
我们可以看到
www.jd.com 的DNS A记录,IP地址是61.174.55.1。
CNAME 下图是查询
www.taobao.com 的抓包。 我们看到
www.taobao.com 转到了
www.taobao.com.danuoyi.tbcache.com。 同时我们也可以看到
www.taobao.com.danuoyi.tbcache.com 有多条A记录,这里就是传说的DNS 负载均衡。