原计划里,切 DNS 是最后一道闸门,排在第 9 阶段。
1 实测 → 2 规划 → 3 打包 → 4 配置 → 5 上传 → 6 启动
→ 7 建站 → 8 证书 → 9 切 DNS → 10 联调 → 11 加固
↑ 不可逆,放最后
这么安排的主要原因是:域名一旦指向新机,旧机就断了流量,中途出问题只能靠改回 A 记录来回滚。
我当时的计划,是把第 1 阶段的实测做完,再一步步往上推。
但我还卡在第 1 阶段做实测的时候,三个域名的 A 记录已经全部改到新机上了。
我用公共 DNS 交叉验证确认过。
nslookup h5.example.com 223.5.5.5 → <新机IP>
nslookup api.example.com 223.5.5.5 → <新机IP>
nslookup admin.example.com 223.5.5.5 → <新机IP>
新机上是这个样子:目录没建、镜像没传、容器一个都没起来。
也就是说,服务此刻正处于中断状态,这个很危险。
很多人遇到这种情况会直接慌,然后开始乱序操作。
先花 30 秒把它拆开看,会发现它其实是同一件事的两面。
坏消息是,域名已经指向新机,可新机上服务不可达,三个入口全废。
好消息是,证书签发不再受 DNS 阻拦了。第 8 阶段本来要绕路,现在可以直接做。
好消息这一条值得展开一下。
Let's Encrypt 的 HTTP-01 验证要求域名解析到本机。
解析不到,验证请求就到不了你的服务器,证书签不下来。
原方案里这一步被卡在「DNS 还没切」,所以我准备了三条绕路:搬运旧证书、改 DNS-01 加 TXT 记录、先切再签。
现在 DNS 已经切了,这个阻碍自动消失。原本要绕的路,不用绕了。
重排之后,顺序变成这样。
第 1 到第 8 阶段照旧往下做,第 9 阶段的切 DNS 从待办变成了已完成,第 10 和第 11 阶段继续往后排。
DNS 从最后一道闸,变成了一个已完成项。
这个拆解的价值在于,它把「完蛋了」拆成了「有一件事变好了,有一件事变急了」。
慌了会乱,拆开了就能排优先级。
然后是第一个陷阱:我一开始看到的那个 502 是假的。
确认中断之后,我做的第一件事是从本地探测。
curl -s -o /dev/null -w "%{http_code}\n" http://h5.example.com/
# 502
502。看起来坐实了「服务挂了」。
但这个证据不能用。理由就在响应里:错误信息带了 os error 10061。
10061 是 Windows 的 socket 错误码,WSAECONNREFUSED,意思是连接被拒绝。而目标服务器跑的是 Linux。
一个 Windows 的错误码,怎么会出现在访问 Linux 服务器的响应里?
答案是,这个请求根本没出我的机器。它被本地的代理或者沙箱截走了,直接返回了一个错误。
这条 502 描述的是我本机的状态,不是服务器的状态。
这里有一条通用规则,我记到现在。
你看到的错误,未必来自你以为的那一层。
判断一条证据能不能用,先问一句:这个错误码可能由哪个环节产生?
os error 10061 这种带操作系统特征的信息,是识别本地污染最快的线索。
同理,看到 ECONNREFUSED (os error 111),那才是 Linux 侧的拒绝。
排除掉被污染的证据之后,真正能定性的是在服务器本机跑这两组命令。
# ① 面板里到底有没有我的站点
find /opt/1panel -name "*.conf" 2>/dev/null | xargs grep -l "example.com" 2>/dev/null | head
ls /opt/1panel/www/sites/
# ② 本机对三个域名的真实响应(不走公网、不经过任何代理)
for h in h5 api admin; do
printf "%-8s " "$h"
curl -s -o /dev/null -w "127.0.0.1 → %{http_code} " --max-time 5 \
-H "Host: $h.example.com" http://127.0.0.1/
curl -sk -o /dev/null -w "https → %{http_code}\n" --max-time 5 \
--resolve $h.example.com:443:127.0.0.1 https://$h.example.com/
done
第二条命令里的两个技巧值得单独说。
第一个技巧是在 curl 里带上 -H "Host: 域名"。
请求打到 http://127.0.0.1/ ,等于伪造一个 Host 头。这等价于域名已经解析到本机,绕开 DNS。
另一个是 --resolve 域名:443:127.0.0.1,只对这一条请求把域名指到本机。它不动全局 DNS,用来在 HTTPS 层做验证。
这两条都不经过公网,所以不可能被本地代理污染。
结果怎么读,一共四种情况。
本机请求返回 000,说明本地 Web 层根本没监听,也就是容器没起。
返回 404,说明 Web 层活着,但站点还没建。
返回 200 或者 301,同时 https 那一侧返回 000,说明 HTTP 通了,HTTPS 还没配。
两边都是 200,服务就已经恢复了。
确认中断属实之后,剩下的问题是:从哪一步开始做?
这时候最容易犯的错,是从头按顺序再做一遍。
可中断恢复的正确排序依据是依赖关系,不是阶段编号。
服务器建目录 → 本地打包(源码+产物+镜像)→ 上传 → 配置定稿 → 启动容器
↑
恢复的临界点
判断标准就一句话:哪一步做完,服务就恢复了?
在这个架构里,答案是容器启动。
对外提供服务的三个容器一旦起来,本机的 127.0.0.1 就通了。站点建好之后,公网也就通了。
于是优先级排成这样。
立刻要做的,是建目录、上传、配置定稿、启动容器。这几件不能延后,它们是恢复的临界点。
紧接着是建站点、签证书,也不能延后,否则公网仍然不可达。
可以慢一步的,是第三方平台联调,也就是登录和支付。它不影响「能不能访问」。
排在最末的,才是安全加固、备份、日志轮转。
「第三方联调可以慢」这一条,是这次重排里最重要的决定。
它通常需要外部平台配合,耗时不可控。要是把它和「恢复服务」混在一起做,中断时间会被它拖长。
还有一条纪律。
在中断状态下,禁止做任何顺手优化。
那 30 分钟里唯一的 KPI 就是恢复。任何顺手改的配置,都会变成新的变量。
这段我固化成了清单,以后直接照着走。
先交叉验证 DNS 的真实指向,两个公共 DNS 返回一致才算数。
接着怀疑本地探测的结果,错误码带 OS 特征的,本机验证重来一遍。
然后在服务器本机定性,把没监听、没建站、没证书这三种情况分开。
再按依赖排出临界点,明确哪一步做完服务就回来。
非阻塞项一律延后,包括外部联调、加固、备份。
恢复之后立刻补基线,同机其他站点的状态码要和中断前一致。
至于那个 502 到底被本机哪个环节截走的,我到现在也没精确查到,只能确认它没出机器。