一次线上 DNS 抖动排查记录
上周三凌晨两点多,监控开始告警。业务本身没有挂,但接口的 P99 从 80ms 左右一路涨到了 400ms,持续了大约二十分钟之后又自己恢复了。因为恢复得太"自然",反而让人更不放心。
告警只出现在同一台机器上,其他实例的指标都是平的。所以第一反应是先看看这台机器本身。
先排除机器自身的问题
登上去之后依次看了 CPU、内存、磁盘 IO 和网卡队列,都没什么异常。负载比平时还低一点。dmesg 里倒是有一行关于 conntrack 表接近上限的提示,但那个进程平时流量不大,不至于成为瓶颈。
于是把范围缩小到"是不是网络问题"。
从连接层往下看
用 ss -s 看了一下 socket 统计,总数正常,没有明显的 TIME_WAIT 堆积。对网关做了两分钟的连续 ping,丢包率为 0,延迟也很稳定。
但有一个细节很可疑:应用日志里偶尔会看到一条 no such host,频率大概每分钟一两条,平时可能根本不会注意。
# 先看看当前用的解析器
$ cat /etc/resolv.conf
nameserver 10.0.0.2
options timeout:2 attempts:2
# 连续打 200 次解析,看耗时分布
$ for i in $(seq 200); do
dig +noall +stats +time=2 api.internal 2>&1 | grep "Query time"
done | sort -k3 -n | tail -5
结果很直观:200 次里有 6 次耗时超过 1.5 秒,最慢的一次接近 2.8 秒。而正常情况下这个值应该在 5ms 以内。
问题出在上游递归解析器
接着直接对 10.0.0.2 这台内网 DNS 做同样的测试,发现抖动只出现在它身上,换一个备用的解析器就完全正常。
联系了平台侧之后确认,那台机器当天凌晨在做一次不重启的热升级,期间有个别请求会因为内部转发队列满而被短暂阻塞。升级完成之后,抖动就消失了。
几个可以带走的经验
- 应用里最好配置多个解析器,并且在客户端层面做失败重试,而不是完全依赖系统的
resolv.conf顺序。 - 把 DNS 解析耗时也纳入监控,不要只盯着请求总耗时——两者混在一起时,很难看出是哪一环拖慢的。
- 出现"自己好了"的故障,往往比一直坏着的更难处理,事后一定要把时间点和外部变更对齐一下。
这次算是运气好,二十分钟就结束了。如果那台 DNS 一直不稳定,影响面会大得多。