一次线上 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 一直不稳定,影响面会大得多。

← 返回首页