关于这个,网上的说明非常多。通俗一点。DNS其实就是一个电话本翻译系统,用来把域名解析成对应的IP地址;
对于前端来说,DNS就是从浏览器输入域名后,浏览器与DNS服务器交互,最终浏览器向DNS解析返回的IP地址建立TCP连接的过程;
这里网络教程也非常多。这里一张图说明。总结一下:
从输入域名到返回结果,经历的每一步,都可能有缓存。如果有缓存,就不会进行下一步,直到达到全球只有13台的跟域名服务器;
大部分开发能接触到的,只有到本地DNS服务器这一层。针对前端开发来说,也只需要了解到这一层即可。本篇幅重点讨论这几个流程间的交互;
使用window Server可以轻易的配置本地DNS服务器。如果你想自己动手试试,可以参考这里
为了测试各个浏览器的DNS缓存,通过如下方式实现;
版本 :100.0.4896.88
项目 | 缓存时间 |
---|---|
关闭浏览器后立即打开 | 20分钟+ |
在页面f5刷新 | 20分钟+ |
在页面ctrl+f5(强制)刷新 | 20分钟+ |
新开标签页复制地址enter | 20分钟+ |
网上的方案如下:
在地址栏输入以下地址回车,点击 Clear host cache 即可:
chrome://net-internals/#dns
然而20分钟过去了。浏览器依旧能够访问删除的DNS地址;
于是我加上了 ctrl+shift+delete,删除浏览器缓存,才恢复了正常;
版本:99.0.1
项目 | 缓存时间 |
---|---|
关闭浏览器后立即打开 | 0 |
在页面f5刷新 | 10分钟 |
在页面ctrl+f5(强制)刷新 | 0 |
新开标签页复制地址enter | 10分钟 |
方案如下:
Firefox 之前有几个扩展非常方便,可惜都已经下线了 (SYSIN):dns-flusher、clear-dns-cache
现在实现方法如下:
在地址栏输入:about:config
,回车,“接受风险并继续”,然后搜索 f
,出现如下 3 项:
400
60
60
0
即可。注意:
修改后为禁用 DNS 缓存 (SYSIN)。
该操作对网络浏览体验可能有一定影响,仅用于调试。
如果有新的扩展出现,使用扩展更佳。
补充:修改上述数组实测浏览器缓存DNS策略不变;
项目 | 缓存时间 |
---|---|
关闭浏览器后立即打开 | 0 |
在页面f5刷新 | 20分钟+ |
在页面ctrl+f5(强制)刷新 | 20分钟+ |
新开标签页复制地址enter | 0 |
需要写注册表。参见 https://www.muzijie.com/a1/v09l1m70.html。我没有尝试过
在操作系统缓存中,包含了host文件的读取。即,如果你的host文件配置了域名,那么匹配上之后,永远不会进行下一步查询(优先级最高);
host文件配置地址:C:\Windows\System32\drivers\etc
配置方式文件内已经给了说明:
# localhost name resolution is handled within DNS itself.
100.100.100.1 console.demo.com
永久(配置后永久生效)
本地host文件
删除对应映射即可。
ipconfig /displaydns
建议通过 查看
ipconfig /displaydns > C:\Users\dnscache.txt
在测试DNS服务器上创建一个新的域名 指向 200.xx.xx.131,发现默认缓存时间是1h(通过不断打印缓存查看)
但是,这个时间受到各种因素影响;例如当我实测禁用/启用本地网卡时,缓存会被重新更新(猜测应该是重新轮询了本地DNS服务器);
通过如下指令可以强制清除本地DNS缓存
ipconfig /flushdns
可以发现清理后,使用缓存查看指令,只能看到如下一些记录:
这部分就是host文件记录的优先级最高的DNS记录了!所以对于host文件记录的内容,不会受缓存刷新影响,也应证了host文件的最高优先级
DNS可以实现一对多。即一个域名对应多个IP。这种情况对于网站保活容灾具有相当的应用价值;
例如我同一个域名,常备4台服务器。常态只有一台服务器活着,其他ip无法ping通。此时dns解析就会优先选择能通的服务器Ip作为解析结果;
但是如果4个ip都通,那么浏览器解析规则是什么呢?接下来我们进行测试;
为了避免浏览器缓存和本地缓存的影响,我们每次测试使用一个新的域名;每个域名均对应2个不同的ip地址(2个ip均可访问,是相同的产品,部署在不同服务器);
5个域名解析结果(IPA 记为 A ,IPB记为B);
是否受本地缓存影响 指不清除操作系统本地缓存下,纯粹通过刷新浏览器,清除DNS缓存,清除缓存等方式,使IP解析结果发生变化;
浏览器 | 首次打开解析地址(5次) | 改变解析地址需要努力 | 是否受本地缓存影响 | 解析改变后是否改变本地缓存 |
---|---|---|---|---|
Firefix | A B B A B | 折腾5分钟 | 否 | 是 |
IE | B B A A B | 15分钟无果 | 否 | 是 |
chrome | A A A B B | 15分钟无果 | 否 | 是 |
edge | B B A A B | 15分钟无果 | 否 | 是 |
结论:
另外在测试过程中发现一点规律:
每次新开一个浏览器解析一个新的域名,windows本地缓存都会发生变化。且解析域名的排列顺序,总是浏览器实际解析出来的域名排在第一个,结合上述数据,证明本地缓存是每次重新解析DNS(向DNS服务器发起请求)后生成的。解析完成后顺便把第一个地址给浏览器;
如下图,108
IP总是新的浏览器解析的ip地址。
浏览器解析域名是否会根据根据服务器的状态选择性使用某台服务器?答案是会的:
验证:新开一个域名对应2个IP地址(ip1,ip1),测试浏览器端访问结果。如果访问到ip1的服务器,则将ip1服务器nginx容器kill掉,亲测浏览器会解析到ip2;
如下图:
由于客户端先前DNS解析到131,故kill掉131后,刷新浏览器,在与131服务器建链失败后(推测是收到了[RST ACK]头),尝试与80(正常服务器)进行通讯,建立client hello;
但是经过我的这篇文章的验证。在一对多域名解析情况下,浏览器进行轮询遍历,此时浏览器只能够识别服务器最基本的端口状态,如果端口完全不存在,才会进行下一个IP的尝试,直到找到一个成功的ip并进行解析;
DNS解析流程在浏览器和客户端层面都有涉及。作为前端开发应该了解其基本原理和缓存机制,方便后续定位解决问题。