① 先把后文会反复出现的词认清楚
先认词:“域名打不开”只是一个表象。这里把真正参与排错的核心词按请求发生顺序展开:名称解析 → 网络连接 → 加密握手 → HTTP 路由 → 应用 → 浏览器安全 → 中国大陆接入合规。每张卡都包含直觉、严格定义、当前案例和边界。
Domain Name System (DNS) · 域名系统 / DNS 解析把人类可读域名解析成地址或别名;它只负责“名字指向哪里”,不负责目标服务是否可用。
- 直觉
- DNS 像互联网电话簿:你输入
api.example.com,先要查到应该去哪个地址,再谈后面的连接、证书和应用。 - 严格定义
- DNS 是分层、分布式名称系统。客户端通常把查询交给递归解析器,递归解析器根据缓存或继续查询根、顶级域与权威 DNS,最后返回 A、AAAA、CNAME 等资源记录及 TTL。权威 DNS 决定某个 zone 的正式答案。
- 当前案例
- 排查时先用
dig或nslookup看不同递归解析器得到的答案。如果权威记录已改但部分客户端仍看到旧 IP,应先考虑 TTL、缓存和解析路径,而不是立刻怀疑 Nginx。 - 边界
- DNS 正确只证明“名称层”成立。它不能证明 TCP 443 可达、TLS 证书匹配、反向代理命中正确站点、应用健康,也不能证明浏览器 CORS 或 ICP 接入条件满足。
DNS Resource Records: A / AAAA / CNAME / TTL · DNS 资源记录A/AAAA 把名称指向 IPv4/IPv6,CNAME 把名称别名到另一个域名,TTL 控制递归缓存可复用答案的时间。
- 直觉
- A 像写一个 IPv4 地址,AAAA 写 IPv6 地址,CNAME 写“请继续去查另一个名字”,TTL 则告诉中间缓存“这份答案大概可以保存多久”。
- 严格定义
- A 与 AAAA 的 RDATA 分别承载 IPv4 和 IPv6 地址;CNAME 表示 canonical name 别名关系,解析器还需继续解析目标名称。TTL 是资源记录的缓存生存时间,不是修改后全球必然同步的精确倒计时。
- 当前案例
- 如果域名同时存在正确 A 与错误 AAAA,支持 IPv6 的用户可能走到错误服务器,而只走 IPv4 的用户一切正常;如果旧记录 TTL 很长,也会出现“有些地方已经好、有些地方仍打不开”。
- 边界
- 记录值正确不等于端口开放,更不等于 HTTPS 可用。CNAME 也不会“转发 HTTP 请求”,它只是改变名称解析链;真正的 HTTP 转发由后面的反向代理完成。
Transmission Control Protocol (TCP) / Port 443 · 传输控制协议 / 443 端口DNS 给出地址后,HTTPS 客户端通常先向目标的 TCP 443 建立可靠连接,连接成功后才进入 TLS。
- 直觉
- IP 像大楼地址,443 端口像具体门牌。你查到大楼在哪,并不代表 443 号门一定开着。
- 严格定义
- TCP 是面向连接的可靠字节流传输协议,建立连接时需要完成握手并维护序号、确认和重传等状态。HTTPS 常使用 TCP 443;连接可能因安全组、防火墙、监听地址、路由或网络丢包出现 timeout 或 connection refused。
- 当前案例
- 可以用
nc -vz host 443、curl -v或 TCP 探测区分“域名已经解析,但网络/端口根本连不上”和“TCP 已通、问题发生在 TLS/HTTP 上层”。 - 边界
ping主要观察 ICMP,不等价于 TCP 443。服务器可能禁止 ping 但 HTTPS 正常,也可能 ping 通而 443 被防火墙拦截。
Transport Layer Security (TLS) / HTTPS · 传输层安全 / 加密 HTTPTCP 建连后,通过证书、密钥协商和握手建立加密且可验证服务器身份的通道。
- 直觉
- TCP 只解决“门能不能打开”,TLS 继续确认“门后是不是我要找的那家服务,并建立一条别人难以偷听和篡改的加密通道”。
- 严格定义
- TLS 握手协商协议版本与加密参数,服务器发送证书链证明域名身份,双方生成会话密钥后再承载加密的 HTTP。客户端还会校验证书有效期、信任链、主机名匹配等条件。
- 当前案例
- DNS 指向正确 IP、443 也能连通,但浏览器报证书域名不匹配或链不可信,就应检查证书、SNI、反代 TLS 配置,而不是继续修改 DNS。
- 边界
- TLS 成功只说明加密连接与身份校验这层成立,不代表 HTTP Host 路由、上游应用、数据库或业务响应正确。
Server Name Indication (SNI) · 服务器名称指示TLS 握手阶段客户端携带目标主机名,让同一 IP 上的服务器选择正确证书和虚拟站点。
- 直觉
- 同一栋楼里住着很多公司,客户端在进门时先报“我要找 api.example.com”,前台才知道拿哪张证书和哪套配置。
- 严格定义
- SNI 是 TLS ClientHello 中的扩展,允许客户端在加密 HTTP 内容发送前就声明目标 server name。服务器据此选择对应证书和 TLS 虚拟主机,因此一个公网 IP 可以承载多个 HTTPS 域名。
- 当前案例
- 直接访问
https://IP可能拿到默认站点证书,而访问真实域名却正常;排查时应使用真实 hostname,或用curl --resolve在固定 IP 的同时保留正确的域名/SNI。 - 边界
- SNI 发生在 TLS 层,不等于 HTTP Host。二者都可能含域名,但发生时间和作用不同:SNI 先选 TLS 身份,Host/:authority 再参与 HTTP 路由。
HTTP Host / Reverse Proxy · HTTP 主机路由 / 反向代理HTTP 请求携带目标主机名,Nginx/Caddy 等反向代理据此和路径规则把请求转发给内部应用。
- 直觉
- 所有请求先到大楼总前台,前台看“你找哪家公司、哪个部门”,再把请求转给真正办业务的后端。
- 严格定义
- HTTP/1.1 使用 Host,HTTP/2/3 使用 :authority 表示目标主机。反向代理可终止 TLS,并按主机、路径、Header 等匹配虚拟站点,把请求转发至 upstream;错误的 server_name、route 或 upstream 会表现为 404、502、默认站点等。
- 当前案例
- 若 TLS 正常但访问域名得到错误页面,可检查 Caddy/Nginx access log、Host 匹配和 upstream health;必要时通过固定 Host 请求判断是否命中了正确虚拟主机。
- 边界
- 反向代理“活着”不等于后端应用健康;502 可能是 upstream 不可达。反向代理也不是 DNS:DNS 决定先去哪台机器,反向代理决定请求到了这台机器后再去哪个内部服务。
Application Programming Interface (API) · 应用程序接口前端或其他程序按约定的 URL、方法、参数和响应结构调用后端能力的契约入口。
- 直觉
- 网络和 TLS 只是把电话接通,API 才规定“你该说什么、服务器应该怎么回答”。
- 严格定义
- HTTP API 通常由 endpoint、method、headers、request body、status code 与 response schema 构成契约。应用层还会处理鉴权、业务规则、数据库与其他依赖,因此 HTTP 能到达服务器不代表 API 语义正确。
- 当前案例
- 域名、443、TLS、反代都正常后,可以单独请求
/health或具体 API,观察状态码、响应体和应用日志,继续区分路由错误、鉴权错误、数据库故障等。 - 边界
- API 200 也不一定等于前端正常;浏览器还可能因为 CORS、前端解析错误或页面状态管理问题无法使用这个响应。
Cloud Virtual Machine (CVM) · 云服务器云厂商提供的虚拟计算主机,承载操作系统、反向代理、应用进程和网络安全配置。
- 直觉
- 它可以理解成租来的远程 Linux 电脑;你能在上面运行 Caddy、Docker、数据库客户端和后端服务。
- 严格定义
- CVM 是基础设施计算实例,具有地域/可用区、虚拟网卡、公网/私网地址、安全组、磁盘等资源。网络入口是否开放、服务监听在哪个地址、实例属于中国大陆还是境外地域都会改变访问与合规条件。
- 当前案例
- 当 origin 位于腾讯云中国大陆 CVM 时,除了检查进程和 443,还要把该实例所属接入商与 ICP 接入备案关系纳入排查;若迁移到境外实例,技术路径和合规条件又不同。
- 边界
- “服务器在线”不等于某个域名已经指向它,也不等于对应端口可达。云主机只是承载环境,DNS、TLS、应用和备案是不同层。
Domain Real-name Verification · 域名实名认证验证域名注册持有者身份与注册信息,解决“这个域名是谁名下”的问题。
- 直觉
- 像给房产证上的产权人做身份核验,它证明谁拥有/注册这个域名,但不等于这个地址上的网站已经获得互联网信息服务备案。
- 严格定义
- 域名实名认证属于域名注册管理环节,通常要求注册者信息满足实名要求。它与 DNS 解析、网站服务器部署和 ICP 备案分别属于不同管理/技术层次。
- 当前案例
- 如果控制台显示域名已实名,只能说明注册主体信息通过;当网站使用中国大陆服务器时,仍需单独核对 ICP 主体、网站备案以及当前接入商关系。
- 边界
- “已实名”不能作为“已备案”的证据,也不能解释 TLS 或 HTTP 错误。排错时不要把身份登记和网络协议混为一层。
Internet Content Provider (ICP) Filing / Access Filing · ICP 备案 / 接入备案中国大陆互联网信息服务的备案与实际接入商关系管理;它是合规/接入条件,不是 DNS 协议的一部分。
- 直觉
- DNS 是告诉访客“店在哪里”,ICP备案/接入备案更像“这家店以这个主体在这个接入场地经营是否完成登记”。
- 严格定义
- 当网站或相关互联网信息服务使用中国大陆接入资源时,需要按现行规则完成相应 ICP 备案;已有备案号但更换或增加中国大陆接入商时,通常还涉及接入备案/接入信息维护。具体要求应以工信部和当前云厂商指引为准。
- 当前案例
- 域名已经在其他平台备案,但现在直接指向腾讯云中国大陆 CVM 时,应核对腾讯云是否已经成为对应接入商,而不是只查看域名实名认证或 DNS A 记录。
- 边界
- 这是合规与平台接入层,不应用技术绕路替代合规判断。备案正确也不能证明服务器进程、证书、反代或 API 健康。
Origin / Same-Origin Policy · 源 / 同源策略浏览器把 scheme、host、port 组合成“源”,并默认限制不同源页面脚本相互读取敏感资源。
- 直觉
- 浏览器不仅问“请求能不能发出去”,还会问“这个页面有没有资格读取另一个地址返回的结果”。
- 严格定义
- Web Origin 通常由协议、主机和端口三元组决定。只要其中关键部分不同,就可能成为跨源请求;Same-Origin Policy 是浏览器安全模型,用来限制一个源的脚本直接访问另一个源的受保护数据。
- 当前案例
- GitHub Pages 页面在
https://xxx.github.io,API 在https://api.example.com,二者 host 不同,因此浏览器会按跨源请求处理,即使 API 本身从命令行访问完全正常。 - 边界
- 同源策略主要由浏览器执行,不是服务器之间的网络 ACL。后端服务到后端服务的 HTTP 调用通常不受浏览器 SOP 约束。
Cross-Origin Resource Sharing (CORS) · 跨源资源共享服务端用特定 HTTP 响应头告诉浏览器:哪些跨源页面可以读取这个响应、允许哪些方法和请求头。
- 直觉
- API 已经把包裹送到浏览器,但浏览器收发室还会检查“发起这个请求的页面是否在允许领取名单里”。
- 严格定义
- CORS 通过
Access-Control-Allow-Origin、允许方法和 headers 等响应信息放宽同源策略;某些非简单请求会先发送 OPTIONS preflight,只有预检通过后浏览器才继续实际请求或允许脚本读取结果。 - 当前案例
- 如果
curl https://api.example.com/health成功,而网页控制台显示 CORS blocked,应查看 Origin、预检请求和响应头,而不是继续排查 DNS/TCP。 - 边界
- CORS 不是认证系统,也不是服务器防火墙。允许某个 Origin 读取响应不代表用户获得业务权限;真正的鉴权仍需 token/session/权限规则。
Health Check / Observability · 健康检查 / 可观测性用专门端点和日志、指标等证据回答“请求到没到、服务哪一层活着、故障发生在哪里”。
- 直觉
- 没有仪表时只能猜“可能是 DNS、可能是 Nginx”;有分层观测后,可以像做实验一样逐个测量每一层。
- 严格定义
- Health Check 是针对进程或依赖暴露的明确健康信号,例如 liveness/readiness;Observability 则通过日志、指标、追踪、请求 ID 等输出帮助推断系统内部状态。排错时应从最小本机路径到公网、域名、浏览器逐层增加变量。
- 当前案例
- 先在服务器本机访问后端端口,再访问反代本机入口,再从公网 IP/域名请求,最后在浏览器复现;结合 access/error log,可以确定故障是在应用内部、反代、TLS、DNS 还是浏览器层。
- 边界
/health返回 200 只证明健康检查覆盖的部分。它不自动证明登录、支付、数据库写入或所有外部依赖正常,因此健康检查要明确自己证明的范围。
② 现在再看这段材料到底在说什么
核心问题不是“域名为什么打不开”,而是:一个浏览器请求从名称解析到页面拿到数据,要穿过多少个彼此独立的门?
工程上最常见的误诊,是看到最终症状都叫“打不开”,于是把所有原因都归到 DNS。实际上同一个表象可以由完全不同的层产生:DNS 可能返回旧地址;443 可能被安全组拦截;TLS 可能拿错证书;Nginx 可能命中默认站点;上游应用可能 502;浏览器也可能已经拿到 200 响应,却因为 CORS 不把数据交给 JavaScript。
事实层
每一层都应该有独立证据。DNS 看解析答案,TCP 看连接,TLS 看握手与证书,HTTP 看状态码和 Host,应用看日志与健康检查,CORS 看浏览器控制台与响应头。
推理层
如果第 k 层的必要条件没有成立,就没有必要先讨论更高层。例如 443 端口根本连不上时,先改 CORS 没有任何意义。
高频风险
用“能 ping 通”证明 HTTPS 正常;用“dig 有 IP”证明网站可访问;用“证书申请成功”证明 TLS 配置正确;用“curl 成功”证明浏览器跨域一定成功。
为什么要按层排查
把请求过程写成串联系统,可以近似认为成功事件需要每一层都成功:
这里不是为了精确算概率,而是建立一个工程直觉:串联系统里任何一层失败,最终用户都只会看到“失败”。因此排错要按依赖顺序找第一个不成立的必要条件,而不是同时改五处配置。
本案例的特殊之处
前端放在 GitHub Pages,而 API 想落到腾讯云中国大陆服务器。这意味着前端静态页面是否能打开,与 API 域名是否能在大陆 origin 上公开提供服务是两条不同路径。前端 200 不证明 API 正常;API 命令行可访问也不证明浏览器 CORS 正常;DNS 正确更不自动解决大陆接入备案问题。
当前参考:腾讯云:如何快速备案您的网站或 APP · 腾讯云:接入备案 · 腾讯云:网站/APP 阻断相关。
前六个步骤按一次 HTTPS 请求的诊断顺序从左到右阅读;第七个是中国大陆公开服务场景的附加合规门,不是 TLS/HTTP 之后又多出的一层网络协议。
先确认权威记录、递归解析器与缓存最终把域名解析到预期地址;这一层不检查 Web 服务是否存活。
地址正确后还必须能建立传输连接;超时、拒绝连接和安全组拦截都发生在 HTTP 之前。
客户端携带目标主机名完成握手,并校验证书链、有效期和域名匹配;直接访问 IP 不能等价替代这一步。
Nginx/Caddy 根据 Host、路径与规则把请求路由到正确站点或 upstream;默认站点和错误 upstream 会产生另一类失败。
反向代理命中后,还要确认应用、数据库、Redis 等依赖真正可用;健康检查与业务日志在这里给证据。
服务器即使返回 200,浏览器仍可能因为同源策略和 CORS 拒绝把响应交给 JavaScript;curl 成功并不能排除这一层。
当中国大陆云资源对公众提供网站或 APP 服务时,需要单独检查备案与接入要求;这是合规条件,不是 DNS 协议的一部分。
结论:DNS 只解决名称到地址;后面仍有 TCP、TLS、HTTP 路由、应用依赖和浏览器 CORS 等独立条件。若中国大陆云资源用于公开网站或 APP,还存在备案/接入这一条件性合规门,因此“解析成功”绝不等于“页面一定能打开”。
边界:这是故障定位顺序,不表示每个协议在所有实现中严格串行,也不替代云厂商、工信部或浏览器的当前规则;实际排障应逐层取得可重复证据。
③ 概念关系与最小知识闭包
最小知识闭包 1:DNS 到底证明了什么?
当 dig +short api.example.com 返回预期 IP,你最多可以说:“我询问的这个解析器此刻给出了这个地址。”如果要更严格,可以分别看本地默认解析器、公共解析器和权威 DNS:
dig api.example.com
dig @1.1.1.1 api.example.com
dig @8.8.8.8 api.example.com
dig +trace api.example.com
如果权威 DNS 已更新、公共递归仍返回旧值,常见解释是缓存尚未过 TTL;如果一部分网络走 AAAA 而 IPv6 目标没有配置好,则可能出现“手机流量打不开、公司网络能打开”这类分裂现象。因此 DNS 诊断要记录查询对象、记录类型、回答地址、TTL 和时间。
最小知识闭包 2:为什么 ping 不是网站验收?
ping 使用 ICMP Echo,而 HTTPS 常用 TCP 443。安全组可以允许 ICMP 却拒绝 443,也可以禁止 ICMP 而 HTTPS 完全正常。因此正确问题不是“机器活不活”,而是“从用户网络到目标 IP 的目标端口能不能建立连接”。
nc -vz api.example.com 443
curl -v --connect-timeout 5 https://api.example.com/health
连接超时通常把注意力放在路由、安全组、防火墙和监听地址;立即 connection refused 更像目标可达但端口没有服务;已经进入 TLS 错误,则说明 TCP 层大概率已通过。
最小知识闭包 3:为什么域名访问和 IP 访问不是一回事?
现代 HTTPS 虚拟主机通常同时依赖 TLS 的 SNI 与 HTTP Host。也就是说,服务器不仅看“你连到哪个 IP”,还看“你说你要访问哪个名字”。这也是为什么下面两条命令语义不同:
curl -vk https://203.0.113.10/
curl -vk --resolve api.example.com:443:203.0.113.10 https://api.example.com/health
第二条既强制连接指定 IP,又保留 api.example.com 作为 TLS SNI 与 HTTP 主机名,非常适合排除 DNS 之后单独验证某台 origin 的证书、虚拟主机与应用。
最小知识闭包 4:HTTP 状态码也在告诉你“失败在哪”
| 现象 | 更可能的层 | 先看什么 |
|---|---|---|
| DNS NXDOMAIN / SERVFAIL | DNS | 权威记录、DNSSEC、递归解析器、域名状态 |
| 连接超时 | 网络 / 安全组 / 防火墙 | 目标 IP、443 入站、监听地址、路由 |
| TLS certificate mismatch | TLS / SNI | 证书 SAN、server_name、SNI 路由 |
| HTTP 404 且是默认页 | 虚拟主机 / 路由 | Host、Nginx/Caddy server block |
| HTTP 502 / 503 | 反代 / 上游应用 | upstream 地址、进程、容器、健康检查 |
| curl 200,浏览器 CORS 报错 | 浏览器同源/CORS | OPTIONS、Allow-Origin、凭证策略 |
| 腾讯云备案拦截页 | 大陆接入/备案 | 工信部备案状态、腾讯云接入备案状态 |
最小知识闭包 5:把故障定位成“最早失败的边”
可以把系统抽象为有向图:节点是 DNS、TCP、TLS、HTTP、App、Browser,边代表“前一层成立才能进入后一层”。排错的目标不是找到所有异常,而是找到从用户到业务结果路径上第一条不能被证据证明的边。这会显著减少同时改配置造成的新变量。
最小知识闭包 6:同一个问题为什么要“外部测一次、内部测一次”
只从用户浏览器外部测试,你能知道最终链路失败,却不容易知道哪一段失败;只在服务器内部测试,你又可能得到“本机全绿、用户仍打不开”的假安全感。最有效的方法是从两端向中间夹逼:外部测试域名与公网 443,内部测试回环应用与本机反代,然后比较两侧最后成功的位置。
例如内部 127.0.0.1:8080/health 成功、本机 443 成功、外部 443 超时,搜索空间基本收缩到主机防火墙、安全组、路由或云平台入口;反之,外部已经收到 502,说明 DNS/TCP/TLS 往往已经走过一大段,应该把精力放在反代到 upstream 的路径。
最小知识闭包 7:缓存会制造“同一时刻不同用户看到不同世界”
DNS 有递归缓存,CDN 有边缘缓存,浏览器也有 DNS/HTTP/TLS 会话相关缓存。一个配置刚修改后,不同观察者可能因为缓存层不同而看到不同结果。这不是“玄学传播”,而是系统中多个带状态缓存节点的正常结果。
所以排错记录应该至少包含时间、客户端网络、解析器、记录类型和响应。只有把观测条件固定住,才有资格比较两次结果。数学上,这相当于承认观测值不是简单的 f(config),而是 f(config, cache_state, observer, time)。
最小知识闭包 8:不要把“成功返回 HTTP”与“业务成功”混为一谈
HTTP 200 只是应用层协议结果的一部分。一个健康检查可能 200,但登录接口因为数据库迁移缺失返回 500;一个 API 可能 200 返回错误业务码;一个 CDN 也可能把旧的 200 缓存继续发给用户。因此发布验收要把“网络可达”“协议正确”“业务行为正确”分成不同 AC。
④ 把真实案例重新还原
案例拓扑
用户浏览器
├─ https://www.example.com
│ └─ GitHub Pages(静态前端)
│
└─ https://api.example.com
└─ DNSPod
└─ 腾讯云中国大陆 CVM
└─ Caddy / Nginx :443
└─ API :8080
└─ PostgreSQL / Redis
现在出现现象:“www.example.com 能打开,api.example.com 看起来也已经解析到服务器,但网页调用 API 失败。”如果只说“DNS 有问题”,信息量几乎为零。正确做法是把事实、推断、未知拆开。
已知事实
静态前端由 GitHub Pages 提供;API 域名由 DNSPod 管理;目标后端计划部署在腾讯云中国大陆服务器。网页前端和 API origin 因而是两个不同的服务边界。
可做推断
如果公共递归解析器已经返回预期 CVM IP,只能排除一部分 DNS 配置错误;仍需继续确认 443、TLS、Host、反代、应用、CORS 与大陆接入备案状态。
关键未知
是否有 AAAA;443 是否监听;证书是否覆盖 API 域名;反代 upstream 是否健康;浏览器实际拿到什么响应;该域名的 ICP/腾讯云接入状态如何。
错误操作风险
同时改 DNS、证书、Caddy、应用配置和 CORS,会让变量爆炸;用香港代理“先绕一下”也不能替代对真实生产架构的合规判断。
诊断路径 A:先证明名称层
dig +short A api.example.com
dig +short AAAA api.example.com
dig @1.1.1.1 api.example.com
dig @8.8.8.8 api.example.com
记录结果,而不是只看“有输出”。你要知道 A/AAAA 分别是什么、是否存在意外旧记录、不同递归解析器是否一致。如果这里错,先修 DNS;如果这里对,就把 DNS 暂时从嫌疑列表中移出。
诊断路径 B:跳过 DNS,单测 origin
curl -vk --resolve api.example.com:443:203.0.113.10 https://api.example.com/health
这条命令非常关键,因为它把“连接哪个 IP”固定住,同时保留正确域名用于 SNI 和 Host。若这条失败,问题在 DNS 之后、浏览器之前;若它成功,而普通域名请求失败,再回头对比 DNS/网络路径。
诊断路径 C:从服务器内部向外证明
# 应用本身
curl -sS http://127.0.0.1:8080/health
# 反向代理是否能到应用
curl -vk https://127.0.0.1/health -H 'Host: api.example.com'
# 监听与进程
ss -lntp
docker ps # 仅当你的运行方式确实是 Docker
systemctl status caddy
如果本机 8080 正常、443 反代失败,就不要去改数据库;如果本机 443 正常、外部连不上,就把注意力放到安全组、防火墙和平台层。
诊断路径 D:最后检查浏览器
浏览器 Network 面板至少记录:请求 URL、方法、是否触发 OPTIONS、HTTP 状态、Response Headers、Console 报错。如果命令行 API 正常而浏览器提示 CORS,那么请求可能已经到达并成功返回,只是浏览器不允许页面脚本读取。
⑤ 概念如何映射到现实
| 阶段 | 要回答的问题 | 最小证据 | 通过后再看什么 |
|---|---|---|---|
| 1. 域名状态 / DNS | 这个名字此刻解析到哪里?A/AAAA 是否一致? | dig、权威 DNS、TTL | IP/端口 |
| 2. IP / TCP | 目标网络路径和 443 能建立连接吗? | nc、curl -v 连接阶段 | TLS |
| 3. TLS / SNI | 证书是否可信且匹配这个域名?虚拟主机选择是否正确? | curl -vk、证书 SAN、SNI | HTTP |
| 4. HTTP / 反代 | Host 是否命中正确站点?upstream 是否健康? | 状态码、Server/代理日志 | 应用 |
| 5. 应用 / 依赖 | API 路由、数据库、Redis 等业务依赖是否正常? | /health、应用日志、request id | 浏览器 |
| 6. Browser / CORS | 页面脚本是否有权读取跨源响应? | DevTools、OPTIONS、CORS headers | 业务验收 |
| 并行:大陆接入合规 | 真实 origin 使用中国大陆云资源时,ICP备案/接入状态是否满足当前要求? | 工信部/腾讯云当前备案状态 | 上线/切流 |
三种常见上线架构怎么判断
| 架构 | 优点 | 代价 / 边界 | 适用 |
|---|---|---|---|
| GitHub Pages + 非中国大陆 API origin | 静态前端简单,API 可独立部署;不把大陆 origin 作为公开入口 | 跨境网络时延、数据合规、供应商和地域都要按真实业务评估 | 原型、早期演示、对大陆低延迟要求不高 |
| GitHub Pages + 腾讯云中国大陆 API origin | 大陆 API 网络条件更可控 | 需要按实际场景完成 ICP/接入要求;还要独立处理 CORS、TLS | 准备长期在大陆提供服务 |
| 统一域名 + CDN/网关 + 多 origin | 可以做缓存、WAF、流量治理、灰度和多地域 | 系统层次更多,诊断必须明确 CDN、边缘、回源各层 | 规模化生产系统 |
⑥ 现在把它当成一道题
dig +short api.example.com 得到正确 IP,但 curl -v https://api.example.com 在 Connecting 阶段超时。你会把 DNS 从嫌疑列表中降到什么程度?下一条最有信息量的检查是什么?curl https://api.example.com/health 返回 200,但 GitHub Pages 中的 JavaScript 调用失败并出现 CORS 错误。网络、TLS、应用三层分别能推出什么,不能推出什么?⑦ 分级提示,最后就是实际答案
Hint 1 · 方向
先画出请求链,并问:当前证据能证明请求已经走到哪一层?优先找“最早还没有被证明成功”的那一层。
Hint 2 · 结构
DNS 正确后,用 --resolve 把 DNS 从变量中移走;命令行成功而浏览器失败时,才重点看 CORS。ICP备案/接入状态作为中国大陆 origin 的并行部署准入条件核对。
Hint 3 · 接近答案
建议顺序:A/AAAA → TCP 443 → TLS/SNI → HTTP Host/反代 → App/依赖 → Browser/CORS;每层只绑定一个最小证据,确认通过后再上移。
答案 · 实际答案
参考解法不是一串“万能命令”,而是一棵按依赖顺序收缩搜索空间的诊断树。
第一步:把症状翻译成层,而不是翻译成猜测
先记录用户看到的精确现象:NXDOMAIN、超时、connection refused、证书错误、HTTP 403/404/502、备案拦截页、还是浏览器 CORS。不同症状已经携带了“请求大概走到哪一层”的信息。不要只记录一句“打不开”。
第二步:证明 DNS
dig +short A api.example.com
dig +short AAAA api.example.com
dig @1.1.1.1 api.example.com
dig +trace api.example.com
如果记录不正确,处理权威记录、TTL、缓存、域名状态;如果记录一致正确,就不要继续频繁改 DNS。注意检查 AAAA,避免 IPv6 路径成为隐蔽分支。
第三步:证明 TCP 与 TLS,并利用 --resolve 隔离 DNS
nc -vz api.example.com 443
curl -vk --resolve api.example.com:443:203.0.113.10 https://api.example.com/health
--resolve 是这类问题的高价值工具:它固定目标 IP,却保留域名语义,因此可以同时验证 TCP、SNI、证书、HTTP Host 和 origin 行为,而不受递归 DNS 当前答案影响。
第四步:从服务器内部验证反代与应用
curl -sS http://127.0.0.1:8080/health
ss -lntp
journalctl -u caddy --since '10 min ago'
# 或查看实际使用的 Nginx / 容器 / 应用日志
如果本地应用都不通,问题在应用或依赖;如果应用通而反代不通,查 upstream、Host、TLS 配置;如果服务器本地 443 通而公网不通,查安全组、主机防火墙、监听地址和平台网络。
第五步:再处理浏览器 CORS
若命令行请求成功而网页失败,打开 DevTools,看是否有 OPTIONS 预检、实际响应码和 Access-Control-Allow-*。带 Cookie/Authorization 的跨源请求还要区分 credentials、允许来源与通配符的约束。此时不要再把 CORS 错误描述成“服务器没有收到请求”。
第六步:并行核对中国大陆接入要求
截至 2026 年 9 月,腾讯云公开文档说明:使用中国大陆境内服务器开办网站或 APP,需要先按相应流程完成 ICP 备案;已在其他接入商取得备案号、现将服务接入腾讯云中国大陆资源时,需要在腾讯云办理接入备案。多个接入商可以同时存在。工程团队应该把“备案/接入状态”当作部署准入条件,而不是 DNS 的一个子选项。
参考:如何快速备案您的网站或 APP · 接入备案 · 网站/APP 阻断相关。
第七步:定义真正的上线验收
迁移能力:以后换技术栈仍然适用
Nginx 换成 Caddy、单机换成 Kubernetes Ingress、DNSPod 换成 Cloudflare、服务器前加 CDN,这套模型都不会失效。你只需要把某一层继续细分。例如 CDN 会在 DNS 与 origin HTTP 之间增加“边缘节点 → 回源”的新边;Kubernetes 会把“反代 → 应用”细成 Ingress → Service → Pod。核心方法仍然是:画出请求图,为每条边定义可观察证据,找到最早失败的位置。