DNS (Domain Name System)是我们每天都用到的协议,CDN (Content Delivery Network)也经常会接触到,但你能说出它们的原理么?
能说出原理的话,有抓包看过它们真实的数据包么?
今天我们就一起通过抓包来深入下 DNS 流程和 CDN 原理吧。
DNS 实现原理
DNS 的流程可以看这张图:
浏览器访问了某个域名,首先会查找浏览器缓存、本地 hosts 文件、DNS 缓存,没有找到的话再去请求本地 DNS 服务器,由它负责完成域名的解析。
本地 DNS 会依次请求根域名服务器拿到对应的顶级域名服务器的地址,然后请求顶级域名服务器,拿到权威域名服务器的地址,之后权威域名服务器会返回最终的 IP 给本地 DNS 服务器,由它再返给浏览器。
比如说 baidu.com 这个域名,根域名是 .,顶级域名(也叫一级域名)是 com,而二级域名是 baidu.com,那会先向根域名服务器查找 com 的顶级域名服务器的地址,然后再向 com 的顶级域名服务器查找 baidu.com 的权威域名服务器的地址。
有的同学可能会问,那 image.baidu.com 或者 xx.yy.zz.baidu.com 呢?
二级域名和更多级的域名都在权威域名服务器解析,域名服务器只有三级。
因为域名服务器之所以这样分级是为了通过负载均衡来分散压力,具体的域名解析都是由各自的权威域名服务器来处理的,根域名和顶级域名服务器只是做了个转发。
三级就已经能达成目的了,更多级可以自己分,比如后面会讲的 CDN 服务就是自己做了更多级的负载均衡。
说到了 CDN,那 CDN 与 DNS 是啥关系呢?
CDN 的实现原理
CDN 不是一种协议,只是基于 DNS 协议实现的一种分布式网络。
前面说到顶级域名和二级域名服务器只是做了转发,最终域名解析都是在权威域名服务器做的。
那权威域名服务器是不是可以再做一层转发呢?
比如下面是百度云 CDN 的原理图:
权威 DNS 服务器通过 CNAME 的配置(DNS 协议里指定别名的方式)把请求转发到了 baidu 的 DNS 服务器,baidu 的 DNS服务器再根据 IP 返回用户所在区域的一台机器的 IP。
这样用户从这个域名下载内容的时候,就找到了最近的一台机器,那速度自然快很多。
这就是 CDN 的原理。
大概介绍了 DNS 和 CDN 的实现原理,下面我们通过抓包来验证下。
抓包验证上述结论
我们一步步来,首先,前面讲到这三级查找是对的么?
浏览器缓存和 DNS 缓存真的存在么?真的会查 hosts 文件么?
我们用抓包工具来验证下:
这种网络包需要用 wireshark 来抓。
抓取网卡的数据包,过滤 DNS 的包:
刷新页面就可以看到所有 DNS 数据包了:
然后你可以打开 chrome://net-internals/#dns ,查询某个域名的浏览器 DNS 缓存:
点击按钮可以清掉浏览器 DNS 缓存:
这证明了浏览器缓存的存在。
我们再往下验证,hosts 真的会生效么?
修改下 hosts 文件,加个配置:
用 ping 命令试了下,真的生效了,这说明 DNS 确实会查询 hosts 文件。
然后继续验证下系统的 DNS 缓存真的存在么?
我 ping 了几次 www.baidu.com,都没有新的 DNS 数据包,说明确实是有缓存的。
可以执行这个命令清掉系统 DNS 缓存: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
我 ping 了两次 www.baidu.com 都没有 DNS 数据包,但是我一清空缓存,再 ping 就有了:
这验证了系统级别的 DNS 缓存确实存在。
也就是说浏览器 DNS 缓存、hosts 文件、系统 DNS 缓存这三步确实都是会经历的:
继续往下看,本地 DNS 服务是啥?
这个可以在“系统偏好设置 > 网络 > 高级”里看到:
确实是有本地 DNS 服务器的地址的,这个一般是运营商提供的,可能每个城市都有一些公共的。这一级也有缓存。
通过这层层缓存加上域名系统本身就是分布式的,这种设计极大的减轻了 DNS 服务器的压力,实现了高并发,这是我们每天都在用的高并发系统。
继续往后看,这三级域名服务怎么验证呢?
可以 ping 一个不存在的域名,比如 ddd1111.com
这时候可以看到请求了 com 的域名服务器,地址是 a.gtld-server.net,没错,这个就是一个顶级域名服务器的域名。
但你再请求一个别的域名,你会发现它并没有从根域名顶级域名开始查,而是直接从权威域名服务器开始的:
没错,这也是缓存,本地 DNS 服务器会把域名对应的权威域名服务器的 IP 缓存下来,直接去那里查。
你会发现有的返回结果是 CNAME,值为一个域名,这个 CNAME 是一种记录类型,别名的意思。之后会再去这里查,最后查到 A 的记录类型,值就是 IP 了。
CDN 就是这么实现的,我们来看一个真实的 CDN 的 DNS 查询的例子:
这是 www.baidu.com 的 DNS 查询结果:
你会发现先通过 CNAME 指向了另一个域名,然后这个域名又给了两条 IP 的结果。
对照下 CDN 的原理图,就知道这俩 IP 都是离用户最近的服务器的 IP 了:
这就是 CDN 的原理。
再来看个 www.juejin.cn 的,他也是用了 CDN 的:
也是同样 CNAME 指向了 CDN 的 DNS 服务器,然后返回了就近的一些服务器的 IP,只不过它的负载均衡的机器更多一些。
总结
我们通过 wireshark 抓包的方式,验证了 DNS 的流程和 CDN 的实现原理。
DNS 的流程是会先查找浏览器 DNS 缓存、hosts 文件、系统 DNS 缓存,然后请求本地 DNS 服务器,由它去一级级查询最终的 IP:
CDN 是基于 DNS 的,在权威域名服务器做了 CNAME 的转发,然后根据请求 IP 的所在地来返回就近区域的服务器的 IP。
这个流程是有一层层的缓存的,而且还是分布式的,是我们接触最多的高并发系统了。