资讯详情

资讯详情

DNS 解析慢 200ms:resolv.conf 与 nscd 的 3 类原因

我不会起名字322· 后端 / 算法 / 数据库 技术栈 力扣 Hot100 Go 项目 Redis MySQL文章目录DNS 解析慢 200msresolv.conf 与 nscd 的 3 类原因一、先量化慢在哪一步二、原因 1resolv.conf 里配置了不可达的 nameserver排查修法三、原因 2没有本地 DNS 缓存选择 1nscdname service cache daemon选择 2systemd-resolved选择 3应用内缓存最推荐缓存的代价四、原因 3IPv6 的 AAAA 查询拖慢解法五、还有一类K8s 里的 DNS 放大六、带走物DNS 解析慢 200msresolv.conf 与 nscd 的 3 类原因一、先量化慢在哪一步DNS 慢通常表现为接口耗时多了几百毫秒但服务端日志里处理很快。第一步是确认这个耗时真的是 DNS。用 curl 拆开看curl-wdns%{time_namelookup} connect%{time_connect} tls%{time_appconnect} ttfb%{time_starttransfer} total%{time_total}\n\-o/dev/null-shttps://api.example.com/healthz输出示例dns0.205 connect0.212 tls0.280 ttfb0.310 total0.315dns0.205—— DNS 花了 205ms占总耗时 65%。确诊。如果dns很小但connect大那不是 DNS 的问题别查错方向。二、原因 1resolv.conf里配置了不可达的 nameserver这是最常见的一类而且现象很有特点时快时慢。/etc/resolv.conf通常长这样nameserver 10.0.0.2 nameserver 10.0.0.3 options timeout:2 attempts:2 rotate解析逻辑是串行的先问第一个超时了才问第二个。如果10.0.0.2这台 DNS 服务器不可达或者丢包严重那么每次解析都要先等一个超时问 10.0.0.2 → 超时默认 timeout:5attempts:2所以是 5×210 秒 问 10.0.0.3 → 成功几毫秒为什么是时快时慢因为 glibc 的 resolver 会记住上次成功的 server除非开了rotate所以有时能直接用好的那台有时又要试一次坏的。排查# 逐个测 nameserver 的响应时间cat/etc/resolv.conf|grepnameserver|awk{print $2}|whilereadip;doecho-n$ip: dig$ipapi.example.com noall stats|grepQuery time||echo超时done修法把不可达的 nameserver 删掉最简单调小超时和重试次数options timeout:1 attempts:1 rotate single-request-reopenoption作用timeout:1单次查询超时改成 1 秒默认 5 秒attempts:1每个 server 只试 1 次默认 2 次rotate轮询 server而不是一直用第一个single-request-reopen解决 A 和 AAAA 并发查询在某些防火墙下的丢包问题single-request-reopen值得单独说glibc 默认会同时发 AIPv4和 AAAAIPv6两个查询共用同一个 socket。某些防火墙/NAT 设备对这种行为处理有问题会导致其中一个查询丢包然后等超时重试 → 表现为偶发 5 秒延迟。开启这个选项后改成分开用两个 socket问题消失。三、原因 2没有本地 DNS 缓存每次域名解析都要走一次完整的网络往返。如果你的应用对每个请求都新建连接或者连接池的空闲超时设得太短那么每个请求都会带一次 DNS 查询。请求 → 建连接 → DNS 查询20~200ms→ TCP → TLS → 发数据 ↑ 每次都要解法是加本地缓存三个选择选择 1nscdname service cache daemon# 安装yuminstall-ynscd# 或 apt install nscd# 配置/etc/nscd.confenable-cache hostsyespositive-time-to-live hosts3600# 正向缓存 1 小时negative-time-to-live hosts20# 负向NXDOMAIN缓存 20 秒suggested-size hosts211systemctlenable--nownscd nscd-g# 看命中率注意negative-time-to-live不存在的域名也要缓存否则每次查一个拼错的域名都会打一次网络往返。选择 2systemd-resolved现代发行版的默认方案systemctlenable--nowsystemd-resolved resolvectl statistics# 看缓存命中情况选择 3应用内缓存最推荐对于 Go 服务在应用层面控制最灵活importnetvarresolvernet.Resolver{PreferGo:true,Dial:func(ctx context.Context,network,addressstring)(net.Conn,error){d:net.Dialer{Timeout:2*time.Second}returnd.DialContext(ctx,udp,10.0.0.2:53)},}// 自己在应用层加一层缓存比如用 singleflight TTL或者更实际的做法用连接池 长连接让 DNS 查询次数降到最低这比加缓存更彻底。缓存的代价DNS 缓存会让故障切换变慢如果某个 IP 挂了要等 TTL 过期才会解析到新 IP。所以对内部服务TTL 可以设长几分钟到小时级对依赖 DNS 做故障切换的场景TTL 要短或者用客户端负载均衡服务发现替代 DNS。四、原因 3IPv6 的 AAAA 查询拖慢前面提到过glibc 默认会同时查 A 和 AAAA。如果你的网络不支持 IPv6但应用/系统启用了 IPv6那么 AAAA 查询会一直超时/失败每次解析都要等它。Go 里也有同样的坑Go 的 resolver 默认也会查 AAAA。如果 IPv6 不通就会拖慢。# 看系统是否启用了 IPv6cat/proc/sys/net/ipv6/conf/all/disable_ipv6# 1 禁用解法方案 1推荐修好 IPv6或者明确禁用它。方案 2在/etc/gai.conf里让 IPv4 优先precedence ::ffff:0:0/96 100方案 3Go 特有强制只用 IPv4// 建立连接时指定 tcp4conn,err:net.Dial(tcp4,api.example.com:443)或者在/etc/resolv.conf加options single-request让 A 和 AAAA 串行避免并发问题。五、还有一类K8s 里的 DNS 放大如果慢的是 K8s Pod那大概率不是上面这些而是ndots 放大Pod 里访问 redis.prod1 个点ndots5 → 依次查 redis.prod.default.svc.cluster.local redis.prod.svc.cluster.local redis.prod.cluster.local redis.prod → 4 次查询前 3 次 NXDOMAIN一次解析变成 4 次往返加上并发高时 conntrack 表被 UDP 填满导致丢包 → 偶发 5 秒超时。解法见 CoreDNS 那篇域名写全NodeLocal DNSCache。六、带走物排查顺序# 1. 确认慢的是不是 DNScurl-wdns%{time_namelookup} connect%{time_connect} ttfb%{time_starttransfer}\n-o/dev/null-surl# 2. 逐个测 nameservercat/etc/resolv.conf|grepnameserver|awk{print $2}|whilereadip;doecho-n$ip: ;dig$ipdomainnoall stats|grepQuery time||echoTIMEOUTdone# 3. 看有没有本地缓存systemctl status nscd systemd-resolved2/dev/null nscd-g2/dev/null|grep-A3hosts cache# 4. 看 IPv6 状态cat/proc/sys/net/ipv6/conf/all/disable_ipv6对应修法原因修法nameserver 不可达删掉坏的 /options timeout:1 attempts:1 rotate没有本地缓存nscd / systemd-resolved / 应用内缓存 / 用长连接IPv6 AAAA 拖慢禁用 IPv6 或options single-request/ Go 用tcp4K8s ndots 放大域名写全 NodeLocal DNSCache一句话结论DNS 慢 200ms 时先用curl -w %{time_namelookup}确认是不是 DNS再逐个 ping 一遍resolv.conf里的 nameserver —— 八成是其中有一台不可达每次解析都在等它超时。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →