DNS 解析时长毁了我精心设计的图床网络架构

本文最后更新于:2025年8月11日 凌晨

去年夏天,我兴致勃勃地写了好几篇博文,详细讲述了我如何搭建博客图床。核心目标很明确:分地区解析 DNS,让国内外的访客都能嗖嗖地加载图片,体验拉满。想法嘛,绝对是走在技术前沿的,堪称完美!然而……现实它总是喜欢给你来点小惊喜,对吧?

955 毫秒! 看到这个 DNS 解析时长的时候,我差点把刚喝下去的霸王茶姬喷在屏幕上。这简直就是一个隐形刺客,在我精心设计的图床网络架构背后,悄咪咪地给了致命一击。想象一下,访客满怀期待地点开你的博客,结果光是为了搞清楚图片服务器在哪,就要等上差不多一秒钟?这体验优化了个寂寞啊!

为啥之前没发现?这得“感谢”DNS 缓存这位老好人。它勤勤恳恳地帮后来的访客记住了答案,让我的本地测试和复访测试都一片祥和。直到最近,有群友向我反馈了首次访问时图片的加载速度过慢,我才如梦初醒。再结合最近为了秋招准备的八股文中里面关于 DNS 解析那套繁琐的流程(递归查询、权威查询、根域名、顶级域名……查个地址堪比查户口本),我瞬间锁定了罪魁祸首:首次访问时的 DNS 解析延迟

来,复盘一下我那“曲折离奇”的 DNS 寻址之旅(访客视角):

  1. 访客想访问 static.031130.xyz 的图片。
  2. 031130.xyz 的权威 DNS: 问了一圈,发现权威服务器原来在 Cloudflare (国外)。
  3. Cloudflare 权威服务器回复: “哦,static.031130.xyz 啊?它是个马甲 (CNAME),真身是 cdn-cname.zhul.in,你去找它吧!”
  4. zhul.in 的权威 DNS: 这次权威服务器在 DNSPod (国内)。
  5. DNSPod 权威服务器回复 (针对国内用户):cdn-cname.zhul.in 也是个马甲 (CNAME),它实际是 small-storage-cdn.b0.aicdn.com,接着找!”
  6. small-storage-cdn.b0.aicdn.com 最终,它可能还会再 CNAME 到类似 nm.aicdn.com 这样的 CDN 节点主机名。
  7. 最终获得 IP 地址,开始连接 CDN 节点下载图片。

发现问题没?关键的第一步和第二步,权威 DNS 查询指向了国外的 Cloudflare! 对于国内用户,虽然最终解析到的 CDN 节点 (small-storage-cdn.b0.aicdn.com/nm.aicdn.com) 是国内的、速度飞快,但光是前两步跨越重洋的 DNS 查询,就足够让首次访问的用户体验跌入谷底。那个 955ms 的解析时长,基本就是花在跟国外 DNS 服务器“跨国聊天”上了。

优化方案:三管齐下,围剿 DNS 延迟

既然找到了病根,就得下猛药:

  1. DNS 预取 (dns-prefetch): 在博客的 HTML <head> 里,早早地加上 <link rel="dns-prefetch" href="//static.031130.xyz">。这相当于浏览器在渲染页面时,就悄悄开始解析图床域名了,等真需要加载图片时,DNS 结果可能已经准备好了,神不知鬼不觉。当然也可以使用 preconnect 等等更激进的策略,但本文着重讲 DNS 解析,因此不做拓展。
  2. 延长 DNS 记录的 TTL (生存时间):static.031130.xyz 这个 CNAME 记录的 TTL 值调大。以前都设置得较短,方便快速切换。现在为了缓存,适当延长(比如几小时甚至一天)。这样,一旦有用户解析过,本地 DNS 服务器就能记住更久,后续用户(包括同一用户再次访问)就能直接从缓存拿到结果,省掉跨国查询。
  3. 釜底抽薪:迁移权威 DNS! 这是最核心的一步。直接把 031130.xyz 域名的权威 DNS 服务器,从 Cloudflare 搬回国内 DNSPod。这样一来:
    • 访客的递归 DNS 服务器查询 031130.xyz 的权威服务器时,直接找到的就是国内的 DNSPod,响应飞快。
    • DNSPod 直接告诉递归服务器 static.031130.xyz -> small-storage-cdn.b0.aicdn.com 完全在国内完成,丝般顺滑,不需要 cdn-cname.zhul.in 当分区域解析的工具人
    • 整个 DNS 解析链路都在国内高速完成,首次访问的 955ms 噩梦彻底拜拜。

效果如何?

受限于 DNS 缓存带来的测试困难,最终的效果确实很难在短时间内测试出来。但迁移权威 DNS 到 DNSPod + 调整 TTL + 加上预取之后,再测试首次访问的 DNS 解析时间总算是降到了可接受的程度,这才是 CDN 优化该有的样子!

教训总结:

  • 别让 DNS 成为性能短板! 尤其是在涉及多地优化时,权威 DNS 的地理位置对首次访问延迟至关重要。能用国内的权威,就别用国外的。
  • 缓存是好东西,但首次访问是软肋。 善用 dns-prefetch 和合理设置 TTL 能有效缓解。
  • 监控和用户反馈是金。 自己的测试环境往往有缓存“美化”,真实世界的首次访问体验要靠更细致的监控和用户的火眼金睛(感谢反馈的朋友!)。

!!! 超级重要补充:警惕 CNAME 拉平 !!!

最后,必须给各位提个醒!如果你和我一样,需要依赖分地区解析来让访客访问到最近的 CDN 节点(比如让国内走国内CDN,国外走Cloudflare),那么千万要避开 CNAME Flattening (CNAME 拉平) 这个“优化”方案

  • CNAME 拉平是什么? 简单说,就是权威 DNS 服务器(比如 Cloudflare)看到你设置了一个 CNAME 记录(比如 static.example.com -> cdn.cname.target.com),它主动帮你去找 cdn.cname.target.com 的最终 A/AAAA 记录 (IP地址),然后把 最终的 IP 地址 直接返回给查询者,而不是返回 CNAME
  • 听起来很美好?它确实能减少 CNAME 链的长度! 但它有个致命缺点权威 DNS 服务器在拉平解析时,会丢掉分地区解析的上下文!
  • 为什么失效? 分地区解析 (DNS ViewGeoDNS) 的功能是在权威 DNS 服务器层面实现的。当权威服务器执行 CNAME 拉平时,它是在它自己所在的位置去查询 cdn.cname.target.com 的 IP。比如你的权威 DNS 在 Cloudflare (美国节点),它拉平查询时,拿到的 cdn.cname.target.com 的 IP 大概率是给美国用户用的最优 IP。然后它把这个 IP 返回给了所有地区的查询者,包括中国用户!你精心配置的让中国用户解析到国内 CDN IP 的策略就完全失效了!
  • 结论: 如果你需要 分地区解析 (GeoDNS) 功能,绝对不要在你希望应用分地区解析的域名上启用 CNAME Flattening (或 ALIAS, ANAME 等实现类似拉平效果的功能)。老老实实用 CNAME 指向另一个支持 GeoDNS 的域名(就像我初始方案里 static.031130.xyz -> cdn-cname.zhul.in,而 zhul.in 在 DNSPod 上做分地区解析),才能保证你的分流策略正确执行。

DNS 解析时长毁了我精心设计的图床网络架构
https://zhul.in/2025/08/11/dns-resolve-time-destroyed-my-optimization-for-pic-cdn/
作者
竹林里有冰
发布于
2025年8月11日
更新于
2025年8月11日
许可协议