公网 DNS 解析超时,CDN 回源为何大面积失败?

权威 DNS 解析变慢,CDN 边缘回源时域名解析超时,引发回源失败与源站 502 大面积告警。

一、问题背景

我们业务静态资源与部分动态接口走自建 CDN,边缘节点就近回源到源站集群 origin.example.com。源站域名通过公网权威 DNS(第三方 DNS 服务商)解析,TTL 设为 60 秒。CDN 边缘节点默认开启"回源前解析域名",每次回源连接都会经过本地 resolver 向公网权威服务器查询 origin.example.com 的 A 记录。

2025 年 6 月 15 日下午,我们收到了一波源站 502 的集中告警,时间点恰好在某第三方 DNS 服务商发布变更公告之后。

二、故障现象

  1. 17:00 起,多个省份的 CDN 边缘节点同时上报回源失败,错误码以 502 / 504 为主;
  2. 监控显示源站本身 CPU、连接数、磁盘 IO 全部正常,源站健康检查通过;
  3. 但从边缘节点 curl 源站域名,偶发 Could not resolve host 或卡住十几秒后才返回;
  4. 直接 curl 源站 IP(绕过域名)则秒回,说明源站服务无问题,问题在"域名解析 → 建连"这一段;
  5. 告警呈现区域性、间歇性,并非全量节点同时挂。
1
2
3
4
# 边缘节点回源日志片段
17:02:11 upstream connect error: origin.example.com resolve timeout (5s)
17:02:13 GET /api/v1/list -> 502 Bad Gateway (resolve failed)
17:02:40 GET /api/v1/list -> 200 OK   (解析恢复)

三、排查过程

第一步:确认问题在 DNS 侧还是源站侧。 在边缘节点分别测 IP 直连与域名访问:

1
2
3
4
5
time curl -s -o /dev/null -w "%{http_code}\n" http://10.20.30.40/api/v1/list
# 200,耗时 0.03s

time curl -s -o /dev/null -w "%{http_code}\n" http://origin.example.com/api/v1/list
# curl: (6) Could not resolve host,耗时 5.00s

直连秒回、域名超时,立即把火力集中到 DNS。

第二步:手动递归解析测试。dig 指定公网 resolver 测试权威查询耗时:

1
2
dig +trace +time=2 origin.example.com
# 到权威服务器一步时长时间无响应,最后;; connection timed out; no servers could be reached

同时用本地 resolver 测:

1
2
3
dig origin.example.com @223.5.5.5 +stats
;; Query time: 4823 msec
;; SERVER: 223.5.5.5#53(223.5.5.5)

权威服务器响应超过 4.8 秒,远超 CDN 回源解析超时阈值(默认 5s),部分请求直接超时。

第三步:对比多 resolver。 换用多个公共 DNS 与运营商 DNS 逐一测:

1
2
3
4
5
6
7
for s in 223.5.5.5 119.29.29.29 8.8.8.8 1.1.1.1; do
  echo -n "$s: "; dig origin.example.com @$s +short | head -1
done
# 223.5.5.5: (空)
# 119.29.29.29: 10.20.30.40
# 8.8.8.8: (空)
# 1.1.1.1: 10.20.30.40

部分 resolver 解析为空,说明第三方权威 DNS 对部分递归节点的响应异常(后来确认是其一次变更导致 Anycast 节点路由抖动,部分 POP 点到权威服务器链路丢包)。

第四步:关联时间线。 查阅第三方 DNS 服务商状态页,发现 16:55 起其部分地区权威节点出现响应延迟升高公告,与我们 17:00 的告警完全吻合。

四、解决方案

  1. 紧急提高 CDN 回源解析超时阈值,从 5s 提到 15s,减少瞬时超时导致的 502:
1
2
# CDN 边缘配置(示例,nginx 风格)
resolver_timeout 15s;
  1. 降低对公网 DNS 的实时依赖:将 origin.example.com 在 CDN 侧改为"IP 直连回源 + 长缓存",即边缘节点不再每次解析域名,而是用配置里的固定源站 IP 列表回源,DNS 只作为兜底:
1
2
3
4
# 回源配置改为 IP
origin_upstream:
  - 10.20.30.40:80
  - 10.20.30.41:80
  1. 为关键域名配置本地缓存 resolver:在 CDN 节点旁部署 dnsmasq,把 origin.example.com 以较长 TTL 缓存,避免每次回源都打公网查询:
1
2
3
# dnsmasq.conf
server=/example.com/119.29.29.29
local-ttl=300
  1. 等第三方 DNS 服务商 17:40 公告恢复后,逐步把解析超时限回 5s、回源恢复域名模式做灰度验证。

五、根因分析

根因是CDN 回源链路对公网权威 DNS 的强实时依赖 + 过短的解析超时阈值,在第三方 DNS 服务商出现区域 Anycast 抖动时被放大成大面积故障:

  • CDN 边缘每次回源都做实时域名解析,TTL 仅 60 秒,意味着几乎没有本地缓存兜底;
  • 解析超时阈值设为 5s,一旦权威 DNS 响应超过 5s(实际到 4.8s 已濒临极限),请求直接判定失败返回 502;
  • 不同边缘节点就近的公网 resolver 不同,抖动只影响部分 POP,因此呈现"区域性、间歇性"特征;
  • 源站完全健康,却被 DNS 这一前置环节"误杀"。

本质是架构上把"边缘回源"和"公网 DNS 稳定性"强耦合,缺少本地缓存与 IP 兜底两层缓冲。

六、预防措施

  1. 回源去域名化:关键回源域名一律用 IP/SLB 地址直连,DNS 仅作为兜底,彻底解耦公网 DNS 抖动的影响。
  2. 边缘节点本地解析缓存:部署 dnsmasq/unbound,对源站域名做分钟级缓存,公网波动时仍能命中旧解析。
  3. 多 resolver 冗余:CDN 节点配置至少两个异构公共 DNS,单点 resolver 异常时自动切换。
  4. 更合理的超时与重试:回源解析超时阈值设为 10–15s,并加上解析失败后的指数退避重试,避免一次性超时即 502。
  5. 权威 DNS 多服务商容灾:核心域名开启 DNS 服务商主备(如主用第三方、备用云厂商 DNS),通过 NS 记录做冗余。
  6. 外部依赖监控:把"核心域名公网解析成功率/耗时"纳入主动拨测(如全国多节点 synthetics),第三方抖动可在用户感知前告警。

七、总结

这次故障教科书式地展示了"源站好好的,前端却 502"的典型链路:公网 DNS 这一看似与业务无关的底层服务抖动,通过 CDN 实时回源解析被放大成大面积故障。

排查的抓手很简单——先做对照实验(IP 直连 vs 域名访问),把问题坐标从"源站/网络/应用"精确定位到"DNS 解析",后面的事就顺理成章了。架构层面的教训更值得记:任何一条关键链路都不该对外部单点(尤其公网 DNS)做零缓存的强实时依赖,本地缓存 + IP 兜底 + 多 resolver 冗余,才是抵御此类抖动的标配。

使用 Hugo 构建
主题 StackJimmy 设计