生产环境必须用net.resolver:它支持自定义dns服务器(如1.1.1.1)、context超时控制、查mx/txt等非a记录,以及kubernetes headless service全量pod ip;net.lookupip仅适用于本地调试或ci脚本中无需定制的快速验证。

别用 net.LookupIP 做生产级 DNS 查询——它不支持超时、不能换 DNS 服务器、查不了 MX/TXT,真要可控,必须上 net.Resolver。
什么时候该用 net.LookupIP,什么时候必须切 net.Resolver
net.LookupIP 只适合本地调试、CI 脚本里快速验证域名是否能通,或者你完全不关心解析路径、超时、DNS 源的场景。它走系统 resolver(/etc/resolv.conf 或 Windows API),自动处理双栈和基础重试,但你没法干预。
以下情况必须用 net.Resolver:
- 要强制走
1.1.1.1:53或内网 CoreDNS/Consul DNS - goroutine 不能卡住:必须用
context.WithTimeout控制查询耗时 - 查
MX、TXT、CNAME等非 A 记录——net.LookupMX等函数底层只认net.Resolver实例 - Kubernetes Headless Service 场景下要拿到全部 Pod IP,得显式调
resolver.LookupIP(ctx, "ip", domain),且不能传"ip4",否则漏 IPv6
net.Resolver 怎么设 DNS 服务器和超时
核心就两个字段:PreferGo 和 Dial。只设 PreferGo: true 不够,必须同时提供 Dial 函数,否则仍 fallback 到系统行为。
Colly 是一个用于 Go 语言的快速开源爬取和爬虫框架。它适用于从简单的页面提取到异步爬虫处理大量页面集合,支持请求回调和结构化解析。
-
Dial是个函数,不是字符串地址;正确写法是返回net.Conn,例如:return (&net.Dialer{Timeout: 2 * time.Second}).DialContext(ctx, "udp", "1.1.1.1:53") - UDP 查公共 DNS:网络名用
"udp",地址写"8.8.8.8:53";TCP 查自建服务可换"tcp",但注意 Cloudflare/1.1.1.1 默认不响应 TCP 查询 - 必须用
context.WithTimeout包裹LookupIP调用,net.Resolver自身不管理上下文超时 - 别漏错误判断:
err可能是*net.DNSError,得用.IsNotFound()区分“域名不存在”,用.IsTemporary()判断是否临时失败(比如 UDP 丢包、防火墙拦截)
查 MX/TXT/CNAME 等非 A 记录的坑点
net.LookupMX、net.LookupTXT、net.LookupCNAME 都是独立函数,参数和返回值完全不同,不能靠 net.LookupIP 替代。
-
net.LookupCNAME("example.com")只返回最终 canonical name,不返回中间跳转链;如果目标没 CNAME,它会 fallback 到 A 记录并返回 IP 字符串(不是错误) - 查 MX 时,返回的
*net.MX结构体含Host和Pref,Host是域名,不是 IP,后续需再查一次 A/AAAA - 大型 TXT 记录可能被截断(TC=1),此时标准库会自动 fallback 到 TCP —— 但前提是你的
Dial支持"tcp"网络类型,否则直接失败
常见错误现象和输入陷阱
最常踩的坑不是逻辑错,而是输入不合规:
- 传带端口的字符串(如
"example.com:443")会报*net.DNSError,Err字段是"no such host",不是格式错误——net.LookupIP只接受纯域名 - 传 URL(如
"https://example.com")同样失败,得先用url.Parse提取Host -
net.LookupHost默认只返回 IPv4,查不到 AAAA;要双栈必须用net.LookupIP - 容器或 Alpine 镜像中
/etc/resolv.conf缺失或配置异常,会导致所有Lookup*直接报"no such host",此时PreferGo: true+ 自定义Dial是唯一出路
真正难的不是写对第一行代码,而是意识到:DNS 解析在 Go 里从来不是“调一个函数就完事”的事——它横跨系统配置、协议细节、错误语义、并发安全四个层面,漏掉任一环,线上就卡死或误判。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










