SRE 必备利器:域名 DNS 探测排障工具

HTTP 域名接口偶发超时时,DNS 解析延迟是常见排查方向之一。本文介绍 dns-lookup-latency 的使用方法、输出含义和 Go 源码实现,帮助 SRE 快速采样域名解析耗时,判断是否需要继续排查 DNS 链路。

作者 巴辉特

问题背景

访问某个 HTTP 域名接口时,如果偶发性超时,原因可能很多:DNS 解析慢、网络质量抖动、对端服务负载高、客户端连接池异常,或者中间代理链路有问题。

在客户端没有良好埋点的情况下,这类问题很难一次定位,只能沿着“DNS -> 网络 -> 对端服务 -> 客户端实现”逐个排查。本文介绍一个小工具 dns-lookup-latency,用于快速采样域名 DNS 解析延迟,先判断 DNS 是否值得继续深挖。

它适合回答两个问题:

  • 某个域名的解析耗时是否稳定?
  • 偶发超时发生时,DNS 解析是否同时出现明显抖动?

使用演示

运行工具并传入域名,就会开始探测。默认每秒探测一次;如果想控制频率,可以传入第二个参数,例如 0.2 表示每 0.2 秒探测一次。

ulric@ulric-flashcat dns-lookup-latency % ./dns-lookup-latency baidu.com 0.2
Apr  7 09:25:15.414 : 26.060 ms
Apr  7 09:25:15.641 : 3.505 ms
Apr  7 09:25:15.846 : 4.584 ms
Apr  7 09:25:16.051 : 1.515 ms
Apr  7 09:25:16.253 : 6.028 ms
Apr  7 09:25:16.460 : 3.329 ms
Apr  7 09:25:16.665 : 2.943 ms
Apr  7 09:25:16.869 : 3.513 ms
Apr  7 09:25:17.073 : 1.969 ms
Apr  7 09:25:17.276 : 2.194 ms
Apr  7 09:25:17.480 : 2.394 ms
Apr  7 09:25:17.683 : 2.211 ms
Apr  7 09:25:17.886 : 3.497 ms
Apr  7 09:25:18.090 : 3.816 ms
Apr  7 09:25:18.294 : 1.672 ms
Apr  7 09:25:18.496 : 2.913 ms
Apr  7 09:25:18.700 : 2.693 ms
Apr  7 09:25:18.904 : 2.640 ms

输出里,冒号前面是时间戳,冒号后面是 DNS 解析延迟,单位是毫秒。

对于内网域名解析,延迟通常应该比较小。如果采样过程中出现明显毛刺,例如平时只有几毫秒,但偶发变成几十毫秒甚至更高,就可以把 DNS 链路作为重点排查对象。

需要注意,DNS 解析慢只能说明“域名解析阶段可能有问题”,不能直接证明 HTTP 接口超时一定由 DNS 引起。更稳妥的做法是把工具输出时间点和客户端超时日志、网络探测、服务端访问日志放在一起比对。

工具源码

这个需求比较简单,也可以用 shell 实现。这里使用 Go 实现,核心调用是 net.LookupIP。源码如下:

https://github.com/UlricQin/dns-lookup-latency

package main

import (
	"fmt"
	"net"
	"os"
	"strconv"
	"time"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Printf("Usage: %s <domain> <interval-seconds>\n", os.Args[0])
		os.Exit(1)
	}

	domain := os.Args[1]

	interval := 1.0
	if len(os.Args) == 3 {
		f, err := strconv.ParseFloat(os.Args[2], 64)
		if err != nil {
			fmt.Printf("failed to parse interval(%s): %v\n", os.Args[2], err)
			os.Exit(1)
		}
		interval = f
	}

	duration := time.Millisecond * time.Duration(interval*1000)

	for {
		resolveDomain(domain)
		time.Sleep(duration)
	}
}

func resolveDomain(domain string) {
	startTime := time.Now()
	_, err := net.LookupIP(domain)
	elapsed := time.Since(startTime)

	if err != nil {
		fmt.Printf("%v : %v\n", startTime.Format(time.StampMilli), err)
		return
	}

	fmt.Printf("%v : %.3f ms\n", startTime.Format(time.StampMilli), elapsed.Seconds()*1000)
}

不到 50 行代码,逻辑很直接:

  1. 从命令行读取域名。
  2. 可选读取探测间隔,默认 1 秒。
  3. 循环调用 net.LookupIP(domain)
  4. 记录调用前后的时间差。
  5. 成功时输出解析耗时,失败时输出错误。

另外,我给大家打包好了二进制文件,可以直接下载使用:

https://github.com/UlricQin/dns-lookup-latency/releases

排查时怎么用

建议按下面步骤使用这个工具:

  1. 先在出现问题的客户端机器上运行,而不是只在本机运行。
  2. 探测业务实际访问的域名,不要只测公共域名。
  3. 让采样覆盖一段完整的故障窗口。
  4. 同步保留 HTTP 客户端超时日志,方便按时间戳对齐。
  5. 如果 DNS 延迟有毛刺,再继续检查本机 resolver、内网 DNS、递归 DNS、缓存策略和网络链路。
现象 初步判断
DNS 延迟稳定,HTTP 仍超时 继续排查网络、对端服务或客户端连接池
DNS 延迟偶发升高,HTTP 超时同时间出现 DNS 链路值得重点排查
net.LookupIP 直接报错 检查域名、解析器配置和 DNS 服务可用性

FAQ

Q1:这个工具能替代完整的 DNS 监控吗? 不能。它适合临时采样和排障验证。长期监控还需要固定探测点、指标采集、告警和历史趋势。

Q2:为什么要在故障客户端机器上执行? DNS 配置、网络出口、缓存和本地 resolver 可能因机器或机房不同而不同。只有在真实客户端环境执行,结果才更接近业务请求路径。

Q3:只看 DNS 延迟就能定责吗? 不建议。DNS 延迟是证据之一,还要和 HTTP 超时、网络质量、服务端负载、日志时间戳一起分析。

如上知识,希望对你有帮助。文末请允许我插播一个小广告。本人创业两年了,我们公司的业务如下,如果你有这方面的需求,欢迎联系我们做产品技术交流哈。

🎯 关于快猫星云

快猫星云是一家云原生智能运维科技公司,由知名开源项目“夜莺(Nightingale)”的核心开发团队组成,创始团队均来⾃阿⾥、百度、滴滴等互联⽹公司。夜莺是一款开源云原生监控工具,是中国计算机学会接受捐赠并托管的第一个开源项目,在GitHub上有超过8000颗星,迭代发布了超过100多个版本,上百位社区贡献者,是国内领先的开源可观测性解决方案。

快猫星云以开源夜莺为内核打造的“Flashcat平台”,是国内顶级互联⽹公司可观测性实践的产品化落地,致力于让可观测性技术更好的服务企业,保障服务稳定性。Flashcat 平台具有以下特点:

  • 统一采集:采用插件化思路,内置集成上百种采集插件,服务器、网络设备、中间件、数据库、应用、业务,均可监控,开箱即用。
  • 统一告警:支持几十种数据源对接,收集各类监控系统的告警事件,进行统一的告警收敛、降噪、排班、认领、升级、协同,大幅提升告警处理效率。
  • 统一观测:将 Metrics、Logs、Traces、Events、Profiling 等多种可观测性数据融会贯通,并预置行业最佳实践,既提供全局业务视角、技术视角的驾驶舱,也提供层层下钻的故障定位能力,有效缩短故障发现和定位时间。

联系我们交流

延伸路径

继续看解决方案和产品对比

如果你正在做监控、可观测性或故障定位相关选型,建议从解决方案和产品对比继续往下看。

标签 DNS
快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云