ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

客观测DNS的正确姿势:从解析原理到全链路测试方法

客观测DNS的正确姿势:从解析原理到全链路测试方法 1. 为什么测DNS——先搞清楚你到底要测什么很多人一提到测DNS第一反应就是跑到网上找一个所谓DNS测速工具点一下得到几个毫秒数字然后挑个数字小的用。这个做法不能说错但实在太粗糙了。我在日常维护服务器和帮朋友处理网络问题的过程中见过太多因为DNS测试方法不对导致明明换了更快的DNS却越用越卡的案例。要客观地测DNS第一步不是打开工具而是想清楚你面临的到底是一个什么样的问题。1.1 DNS解析链路的完整环节DNS看起来就是一个输入域名、返回IP的过程但这条链路上有好几个环节任何一个环节慢都会体现为DNS慢而它们的解决方法完全不一样。一次完整的DNS解析通常经过这几个节点本地DNS缓存操作系统或浏览器会缓存历史解析结果Windows上有DNS Client服务Linux发行版通常有systemd-resolved或dnsmasqChrome也有自己的缓存。命中缓存时解析几乎是0毫秒。递归解析器Recursive Resolver你配置的DNS服务器无论是运营商的还是公共DNS会替你去查询。这个环节慢大多数情况下不是你配置的DNS服务器本身慢而是它向上级权威节点发起请求耗费了时间。权威DNSAuthoritative Server真正持有域名解析记录的服务器比如你域名所在注册商提供的NS服务器或者云服务商的解析服务。权威DNS本身的响应速度、部署地域、是否抗攻击直接影响整体解析时间。根服务器与顶级域Root/TLD递归器需要逐级往下问先问根再问顶级域如.com最后才能找到权威。正常情况下这个环节对用户无感但极端情况下比如根服务器异常或被攻击会拖慢一切。测量DNS之前先定位你的慢发生在哪一环否则测出来的数据没有指导意义。比如你测某个公共DNS延迟很高但换一台电脑同一个DNS却很快这往往不是DNS本身的问题而是中间网络链路的问题。1.2 四个核心测量指标延迟、成功率、一致性、安全客观测DNS不能只看快不快至少要从四个维度看。延迟Latency从发起查询到收到响应的时间。单次查询的延迟意义不大因为受网络波动影响太大需要多次取样看分布。成功率Success Rate1000次查询里有多少次能返回正确结果。有些DNS在高峰期会丢包或超时这在单次测试中根本看不到。一致性Consistency同一时刻查询同一个域名不同DNS服务器返回的IP是否一致。如果某个DNS返回的IP与权威记录不符说明它做了劫持或缓存了脏数据。安全Security是否支持DNSSEC验证、是否强制跳转广告、是否存在NXDOMAIN篡改把一个不存在的域名解析到某个广告页面。这个维度最容易被忽略但恰恰和用户体验强相关。我个人的建议是做DNS对比至少要让测试持续24小时跨越早、中、晚三个高峰时段。毕竟晚高峰打开网页卡死这类问题往往只在特定时段才出现。2. 常用DNS测试工具——从命令行到在线平台搞清楚了要测什么接下来选工具。DNS测试工具分成几类各有各的适用场景。我平时最常驻的是命令行工具因为它们可控性强、能拿到最原始的返回数据。但如果只是帮家里老人选一个上网更快的DNS我也会简化成三个在线平台交叉验证。2.1 dig/nslookup的基础查询与对比用法**digDomain Information Groper**是Linux/macOS上最强大的DNS查询工具。它返回的信息完整包括查询的服务器、耗时、Flags、应答段等。我第一次用dig的时候光看它那一大坨输出就懵了但理解了结构之后它就成了我判断DNS问题的第一把尺子。常用命令示例# 指定DNS服务器查询域名A记录并显示时间 dig 223.5.5.5 www.example.com A time5 tries1 # 只显示关键结果去掉冗长的辅助信息 dig 8.8.8.8 www.example.com A short # 查看查询耗时 dig 114.114.114.114 www.example.com stats | grep Query timetime参数指定超时秒数tries指定超时后重试次数。线上排查时我通常把tries设为1避免一次卡住浪费大量时间。Query time那一行显示的是本次查询从发出到收到响应的毫秒数这就是最基础的延迟数据。Windows上的nslookup则相对轻量# 指定DNS服务器 nslookup www.example.com 223.5.5.5 # 查看详细响应 nslookup -typeA www.example.com 8.8.8.8nslookup在交互模式里输入server 8.8.8.8可以切换服务器这个技巧适合批量对比多个DNS时快速操作。这里要特别提醒dig和nslookup测出来的延迟是你到DNS服务器这一段的往返时间加上该DNS服务器向上级递归的时间。如果你和一个DNS服务器之间的物理延迟本身很高即使它上游解析极快你感受到的依然是慢。2.2 专项测速工具dnsperf、dnslookuptime与在线平台如果要正规一点做压测dnsperf是ISC出品的工具专用于DNS服务器性能测试。它可以从一个文件里读取大量域名以固定QPS每秒查询数向目标DNS发送请求最后统计延迟分布和丢包率。一个典型用法# 从文件读取域名列表持续20秒向223.5.5.5发送查询 dnsperf -s 223.5.5.5 -d domains.txt -l 20 -c 100其中-c 100表示并发查询数。dnsperf输出的报告包含Avg latency、Lost queries等关键数据用来对比不同DNS在高并发下的表现非常直观。在线平台方面我常用的有三类DNSPerfdnperf.com之类展示全球各大公共DNS的实时延迟和可用性排名适合宏观了解趋势。国内的测速平台比如一些网站提供的DNS测速本质是从你所在位置向多个DNS服务器做ICMP ping或TCP/UDP查询结果只代表当前网络下到目标DNS的延迟不代表解析质量。云厂商的拨测工具如果你有云服务器可以用云厂商提供的网络拨测或DNS监测服务支持在全国甚至全球多个节点同时发起查询能帮你判断是某个地区慢还是你的目标DNS整体慢。工具不在多关键在于了解每种工具能回答什么问题。用在线平台跑出的延迟排行榜只能做个粗略参考真要换DNS还是得回到命令行做可复现的测试。2.3 Wireshark抓包分析——深入确认问题命令行工具能告诉你慢Wireshark能告诉你为什么慢。在排查DNS问题时抓包分析可以确认查询是UDP还是TCP发出超过512字节的响应会切到TCP个别情况下TCP被防火墙拦截会导致解析失败。是否存在大量重传Retransmission说明UDP包在网络里丢了。响应包是否来自你配置的DNS服务器还是来自其他IP可能是劫持。TTLTime to Live是否正常不正常的TTL往往意味着缓存层在搞鬼。Wireshark抓DNS包的过滤器很简单dns或者port 53。发起一次解析看请求和响应的间隔再用Follow UDP Stream查看完整内容。这个方法对普通用户有点重但只要你吃过一次看似DNS慢实际是网络丢包的亏就会心甘情愿学起来了。3. 客观测试的方法论——别让单次结果骗了你3.1 控制变量固定查询端、固定查询工具有个常见误区拿手机上的测速App对比两个DNS发现A比B快10ms就断定A更好。这里至少有三个变量没控制住手机Wi-Fi信号波动、查询的域名不同、每次查询经过的网络路径不同。我做相对严格的DNS对比时会遵循几个原则同一台设备最好用有线连接的电脑避免Wi-Fi干扰。同一个解析目标固定几个有代表性的域名比如一个大型门户缓存命中率高、一个冷门个人站需要完整递归、一个CDN商业站点解析结果会有地区差异。同一时段交替测比如每5分钟切换一次DNS循环跑12小时。同一工具统一用dig或dnsperf避免不同工具的实现差异。没有控制变量的测试数据再好看也只能当段子听。3.2 延迟统计平均值的陷阱与百分位数的价值很多人报告延迟只报平均值这其实很坑。DNS查询延迟通常不是一个正态分布偶尔一次超时比如2000ms会把平均值拉得极高而实际体验中99%的请求可能都在30ms内。拿我实测的一组数据举例某个DNS测试100次平均延迟96msP50中位数28msP95210ms超时次数3次2000ms超时如果只看平均值你会觉得这DNS很慢。但P50只有28ms说明正常情况下它非常快问题在于有一小撮请求异常超时。这类DNS适合大多数场景却不适合对可用性要求极高的应用。所以在对比DNS时至少要看P50、P95、P99和超时率这4个数。命令行工具要统计百分位数略微麻烦一个简单的做法是用脚本把dig的Query time全部收集起来然后用awk排序算分位。比如for i in $(seq 1 200); do dig 223.5.5.5 www.example.com noall stats | grep Query time | awk {print $4} done result.txt # 排序并统计百分位 sort -n result.txt | awk -v total200 BEGIN{p50int(total*0.5); p95int(total*0.95)} NRp50{median$1} NRp95{p95val$1} END{print P50:, median, P95:, p95val}这种粗糙但有效的脚本很多地方都适用。严重时我会直接导出到Excel或用python处理目的只有一个看清延迟的真实分布。3.3 缓存、本地递归与权威解析的判断还有一个高频坑测试时命中了缓存会把DNS很快的假象当成结论。Windows默认开启了DNS Client缓存Linux的systemd-resolved、dnsmasq、nscd也都有缓存。同一个域名短时间内重复查询第二次开始很可能是从缓存返回的速度当然快。要测真实解析速度得先清理缓存Windowsipconfig /flushdnsLinuxsystemd-resolvedsystemd-resolve --flush-cachesmacOSsudo killall -HUP mDNSResponder浏览器层Chrome访问chrome://net-internals/#dns点Clear host cache如果不想频繁清缓存实用技巧是在dig命令里加一个随机域名后缀比如查询example.com.test-12345.com前提是你构造的域名确实有解析记录或者用受控的测试域名。这样每次查询都是全新记录绕开缓存干扰。更进阶一步要区分递归器到权威的耗时和本地到递归器的耗时可以用dig trace。它会显示整个递归链路上每一级的耗时dig trace www.example.com输出里每一节都有time字段显示该级查询的花费时间。如果大部分时间耗在最后权威DNS响应上说明问题在上游你换本地配置的公共DNS不一定管用。4. 实战全链路DNS测试操作流程4.1 确定测试范围与样本集正式开始测试前先明确几个问题你是在选一个家里或办公室用的DNS还是要在服务器上配置DNS你的网络是电信、联通还是移动不同运营商访问同一个公共DNS体验差异可能非常大。你最常访问哪些网站国内站为主还是国外站为主这个答案决定了测试域名的选择。我做样本集时通常分三类超热域名比如 qq.com、taobao.com、baidu.comCDN覆盖好递归器往往有缓存测的是缓存命中后的速度。普通中小网站比如一些技术博客、社区网站需要递归器做完整解析测的是递归路径效率。不常见域名/新注册域名完全没有缓存测的是最坏情况下的解析能力。每类选3-5个一共10-15个域名基本就能覆盖日常使用情况了。4.2 DNS延迟批量测试脚本我自己长期用这样一个脚本在Linux下跑结果一目了然#!/bin/bash # 简单DNS对比脚本用法: ./dns_test.sh 223.5.5.5 8.8.8.8 114.114.114.114 dns_list$ domainswww.taobao.com www.zhihu.com blog.example.org test-nocache-9527.example.net for dns in $dns_list; do echo DNS Server: $dns for domain in $domains; do result$(dig $dns $domain time3 tries1 noall stats 2/dev/null | grep Query time) echo $domain: $result done done如果不想写脚本也可以直接用dig循环加grep效果类似。关键是每次查询之间要sleep 1避免短时间内重复被缓存影响。这个脚本测出来的是单次延迟更精确的统计脚本在上面3.2已经提过了。4.3 结果记录与对比分析假设我对比两个DNS得到这样一组原始数据域名DNS-A223.5.5.5DNS-B8.8.8.8www.taobao.com12ms210mswww.zhihu.com15ms230msblog.example.org32ms250mstest-nocache-9527.example.net180ms320ms如果只看前两行A完胜。但第四个域名暴露了问题A在处理无缓存冷门域名的递归时比B只快一点甚至可能更慢。如果你的主要场景是访问大型门户网站A更好如果你跑爬虫、监控、大量访问小众网站差距就不那么明显了。我一般会再做两组数据成功率每个DNS连续查询500次统计超时和SERVFAIL的比例。解析一致性对比解析出的IP是否与权威结果一致用dig trace拿到权威答案做基准。这两项数据异常比延迟高更致命。延迟高还能忍解析错是真断网。5. 常见问题与故障排查实录5.1 延迟忽高忽低先排除网络链路问题现象同一DNS白天10ms晚上变成200ms或者每隔几秒一次高延迟。排查步骤先ping目标DNS服务器看ICMP延迟是否也波动。如果ping稳定但DNS延迟波动说明丢包或限速发生在UDP 53端口如果ping也跟着波动大概率是物理链路问题。检查本地网络是否存在P2P下载、视频会议等占用带宽的活动。带宽打满时DNS包虽然小但也会排队。尝试切换DNS端口到TCP 53或者853DNS over TLS测试看是否有改观。有时运营商对UDP 53做了限速或特殊处理。在三个不同时段各测5分钟判断波动是否规律性。我遇到过最典型的案例公司办公网里有人整天跑BT下载路由器连接数被打满任何DNS查询都超时。这种情况下换什么DNS都白搭问题根本不在DNS。5.2 解析结果不一致或疑似污染的判断现象同一个域名用223.5.5.5查出来是A地址用8.8.8.8查出来是B地址甚至用114.114.114.114查出来一个你根本不认识的IP。处理步骤用dig trace看权威DNS的原始应答是什么以权威的结果为准。对比各家DNS返回的TTL。如果TTL异常低比如几秒说明有缓存层在频繁刷新可能有人在中间改数据。用nslookup -typeNS查询该域名的NS记录看是否与你预期一致。如果NS记录被篡改解析结果自然不可信。这种问题在公共Wi-Fi、校园网和某些合规设备上比较常见。遇到域名解析到明显异常IP比如被指向一个IP段不匹配的地址建议先用Wireshark抓包确认是不是你发出的查询和收到的响应真的来自目标DNS服务器。5.3 本地缓存与系统配置对测试结果的干扰现象换一个DNS之后访问网站还是旧的IP甚至打不开。原因系统缓存的TTL还没过期。不少操作系统和浏览器会无视TTL强制缓存比如Chrome默认的缓存策略就不是完全遵守TTL。Windows的DNS Client服务也会缓存失败结果Negative Caching导致一个域名解析失败后短时间内怎么查都失败。解决办法清缓存上面提过的ipconfig /flushdns、systemd-resolve --flush-caches、killall -HUP mDNSResponder。Chrome用户可以访问chrome://net-internals/#dns和chrome://net-internals/#sockets分别清空DNS缓存和Socket池。测试时尽量用无缓存的查询方式例如dig加trace或noadditional或者直接查一个没有历史记录的随机子域名。要特别提醒的是改完DNS一定要重启一下网络服务或电脑再验证因为有些情况下旧缓存在内存里还能存活很长一段时间。5.4 操作系统不同带来的测试差异Windows上的DNS Client服务有一个特性它会对多个网卡同时发起DNS查询然后选最快返回的结果。所以Windows下测延迟得到的往往是多路查询最快那一组的结果和Linux下单一源IP查询得出的延迟没有可比性。Linux下又要看发行版Ubuntu的systemd-resolved默认是stub模式127.0.0.53你配置DNS时既要看/etc/resolv.conf又要看/etc/systemd/resolved.conf两者不一致就会踩坑。现在很多配置工具比如netplan或NetworkManager日常管理DNS直接用命令行改/etc/resolv.conf可能重启后就失效了。所以跨设备对比DNS时最好都在同一操作系统甚至同一设备上做不然数据混淆了很难解释。6. 公共DNS对比与选型心得测试做到最后总归要落到我该用哪个。下面是我在众多测试项目里积累的一些观察不代表任何官方结论只是个人经验。6.1 常见公共DNS的客观观察DNS优势场景需要警惕的点223.5.5.5 / 223.6.6.6阿里DNS国内访问快与阿里云生态联动好个别地区、个别时段可能延迟波动119.29.29.29腾讯DNS国内延迟整体稳定DoT/DoH支持完善对部分海外域名的递归质量一般114.114.114.114 / 114.114.115.115老牌调度节点多抗丢包能力不错部分场景存在广告拦截等附加行为8.8.8.8 / 8.8.4.4Google DNS全球覆盖广海外域名解析质量高国内访问延迟高偶发丢包1.1.1.1Cloudflare DNS全球节点多加密查询支持完善国内部分网络环境下延迟波动较大从多轮测试项目看国内用户访问国内网站阿里和腾讯的DNS延迟普遍低访问海外网站Google和Cloudflare在解析质量上有优势但受网络链路影响明显。各家DNS在不同运营商、不同省份的表现差异很大别人推荐的最快DNS到你那儿可能完全不是那么回事。6.2 按场景选择DNS而不是按排行榜我的建议很简单家用上网、看视频、打游戏优先选国内公共DNS延迟低国内CDN调度准。个人博客、网站运维看权威NS和递归器的组合解析速度和稳定都重要建议开启DNSSEC。爬虫、API调用、数据中心服务器要做压测优先看P95和成功率延迟稍高也能接受。对隐私敏感的用户优先支持DoH/DoT的DNS避免明文查询被中间设备记录。不要机械地在一台机器上把所有流量都指定一个DNS。现代系统大多支持按网络接口或按域名配置不同的解析器善用这些功能比一个DNS打天下要科学得多。6.3 关于本地部署DNS的一点观察热词里有搭建自建DNSlinux配置DNS问题我也跑过本地DNS服务如dnsmasq、Unbound、CoreDNS。结论是家庭网络规模下本地缓存服务器确实能降低重复查询延迟但收益没想象中大。原因是公共DNS本身已经做了大量缓存你再去套一层本地缓存只是把到公共DNS的查询变成了到本地缓存的查询而公共DNS到权威链路的耗时省不掉。只有以下场景本地DNS价值明显内网有大量设备重复域名查询很多。需要内部域名映射比如开发环境里的myapp.local。需要统一切到DoH/DoT在网关层做转发。如果你只是想让上网快一点先测延迟再换公共DNS比搭一个自建DNS要省事得多。自建DNS的配置和维护一点都不简单尤其是systemd-resolved、dnsmasq、iptables的配合坑多到能写一本书。7. 一个完整的24小时测试案例最后分享一个我在帮朋友家庭网络更换DNS时做的完整测试过程这个案例基本把所有流程串起来了。朋友抱怨晚上刷视频卡打开网页时不时转圈。他家是电信200M光纤通过路由器拨号所有设备走Wi-Fi。我先做了基础排查发现路由器WAN口连通性正常带宽也达标问题集中在域名解析上。我挑了三个候选DNS223.5.5.5阿里、119.29.29.29腾讯、默认运营商DNS。测试方法用笔记本有线接入路由器lan口避免Wi-Fi波动。用dig对10个域名循环查询每5分钟切换一次DNS跑满24小时。记录每组的Query time、超时次数和解析IP一致性。结果很有意思运营商默认DNS在工作日和周末晚上都会有规律性的延迟飙升P95经常到500ms以上甚至有2%左右查询超时。而阿里和腾讯DNS整体稳定P95基本在100ms以内。阿里DNS在访问电商类域名时延迟略低腾讯DNS在视频类域名上表现稍好差距大约在10-20ms属于感知不出来的范围。最后给朋友的建议是把路由器的DNS改成阿里和腾讯的主备组合。两周后反馈晚高峰转圈现象基本消失。这个案例里最关键的不是我的测试脚本多高明而是测试覆盖了24小时、控制了设备变量。如果我只是拿测速软件点两下很可能得出三个DNS差不多的错误结论然后问题继续存在。8. 写在最后的几点心得做了这么多次DNS测试我最大的感受是测DNS并不需要多高深的工具但需要耐心和方法论。工具会骗人单次数字会骗人只有样本量足够大、控制变量足够严格的结果才是真正客观的结论。从另外一个角度说DNS只是网络访问链路上的一环。好不容易把DNS延迟从200ms优化到20ms结果发现网页打开慢的根源是服务器带宽不足这种白忙活一场的经历我也没少遇到。所以建议你在下结论之前把整个访问链路——DNS、TCP连接、TLS握手、首字节时间——都粗测一遍确认DNS确实是瓶颈再投入精力去优化它。最后分享一个实用小技巧如果你只是临时测试一个DNS靠不靠谱不用写脚本直接用系统自带的ping看丢包率再用dig看解析是否正常最后访问几个日常网站感受一下。三分钟就能有个初步判断。只有需要横向对比多个DNS、或者要做长期稳定性评估时才需要把整套方法搬出来。工具永远是服务于决策的别为了测试而测试。
返回列表