1. 为什么要做前端域名容灾:先想清楚故障到底发生哪一层
先说一个真实场景。去年我们负责的一个面向 C 端的运营活动页,凌晨两点突然有用户反馈页面打不开、接口大面积报错。排查了十来分钟才发现,不是后端崩了,也不是数据库慢查询,而是我们依赖的主接口域名在部分地区解析异常,CDN 的节点也出现了区域性回源失败。那一刻你会发现,后端服务一切正常,但用户就是进不来,因为入口域名本身已经“不可达”了。
这类问题在后端视角里很容易被忽略,因为服务端监控看到的各项指标都健康,但站在前端视角来看,这就是一次完整的“站点不可用”事故。域名容灾要解决的本质问题就是:当主用域名在 DNS 解析、网络连通性、证书校验、CDN 回源等任意环节出现故障时,前端能否自动切换或降级到备用入口,让用户无感或尽可能少感知地继续使用产品。
很多人听到“域名容灾”第一反应是运维的活,跟 DNS 和负载均衡有关,前端能做什么?其实不是这样。前端能做的方案并不少,而且越是贴近用户端的容灾手段,切换速度越快、对故障的感知越精准。前端域名容灾至少有四种可选路径:DNS 多 IP 与智能切换、HTTPDNS 改造、静态资源多域名冗余、以及本文重点要讲的请求封装(Request Wrapper)。它们分别作用在网络的不同层级,各有各的适用场景、接入成本和控制粒度。
这篇文章我打算把这四种方案完整拆一遍,说清楚各自的原理、优点、坑点,以及我们团队为什么最后选了请求封装。如果你正在做前端架构、性能优化,或者准备面试时被问到“前端怎么做高可用”这类话题,这篇内容应该能帮你省不少翻资料的力气。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 四种主流域名容灾方案拆解
2.1 方案一:DNS 多 IP + 智能 DNS 切换
这个方案其实是偏运维侧的经典做法,但前端也必须理解,因为很多前端同学手里的“域名容灾”方案就是这个的衍生品。
基本原理不复杂:一个域名在权威 DNS 上配置多条 A 记录或 AAAA 记录,对应不同机房的 IP。正常情况下,Local DNS 会根据轮询或就近原则返回其中一个 IP。当某个机房故障时,运维人员通过切换 DNS 解析结果,把流量导向健康机房。更高级一点的是结合拨测系统,由监控程序自动检测各 IP 的可用性,发现异常后自动修改解析记录,实现故障转移。
听起来很顺滑,但它有几个先天短板。首先,DNS 解析结果存在缓存,这个缓存既包括 Local DNS 上面的 TTL,也包括操作系统和浏览器层面的 DNS 缓存。即便你在权威 DNS 上把解析结果改掉,全网生效仍然需要几十分钟甚至更久。那些号称秒级切换的方案,通常是把 TTL 调得很低(比如 30 秒),但低 TTL 会显著增加 Local DNS 的查询压力,并不是所有场景都适合。其次,这个方案只解决“域名解析到哪个 IP”的问题,一旦域名本身被精准封禁或权威 DNS 被污染,你连解析都拿不到正确结果,后面的一切都无从谈起。
结论是:作为前端,可以了解这个方案,但别指望它能解决所有前端侧的容灾问题。它更多是基础设施层面的第一道防线,前端无法主导它的切换时效。
2.2 方案二:HTTPDNS 客户端改造
DNS 解析不可控的问题催生了 HTTPDNS。做法是前端不再走系统默认的 Local DNS 去解析域名,而是通过 HTTP 接口直接向服务商(阿里云、腾讯云都有对应产品)请求某个域名的 IP 列表。拿到的是精准的、基于用户出口 IP 选路后的 IP,既能避开 Local DNS 被劫持/污染的问题,还能拿到多个候选 IP 做连接级别的容灾。
HTTPDNS 的粒度比传统 DNS 细很多。它能在客户端拿到多个 IP,并且 SDK 内部有健康检查机制:当前 IP 连接失败,自动换下一个 IP。如果你的 App 是原生客户端,且公司有自建的 HTTPDNS 服务,这套方案会非常顺。
但放到纯前端项目里,HTTPDNS 没那么好落地。浏览器环境下,你很难绕过系统 DNS 去自定义连接 IP,除非用 WebSocket 这类不依赖标准 DNS 的连接方式,又或者自己做私有协议,这已经超出常规 Web 应用的范畴了。倒是小程序、uni-app 这类运行在特定容器里的场景,有部分容器能力允许配置域名解析或使用内嵌的 HTTPDNS SDK,但兼容性和平台政策限制都比较多。
所以 HTTPDNS 是重型方案,适合大厂自研 App 的客户端团队,不适合普通前端团队在 Web/H5 项目里快速落地。如果你们是混合开发,App 壳里接一套 HTTPDNS 倒是可行,但那就属于客户端改造的范畴了。
2.3 方案三:静态资源多域名 + 域名替换
这个方案在页面依赖大量 JS/CSS 资源的场景里很常见。你的 JS 文件、CSS 文件、图片等静态资源,分散存放在多个 CDN 域名下,比如 static1.example.com、static2.example.com。正常情况主域名加载,主域名失败时切换备用域名。
静态资源的容灾和接口容灾有一个明显区别:静态资源是通过 <script>、<link> 标签加载的,它们的加载失败不像 fetch/XHR 那样有清晰的 catch 回调。所以很多团队会用一个备用域名动态加载 JSONP 探活文件,比如在主资源加载失败后,动态插入一个指向备用域名的 <script>,如果它成功执行了
