公网 502、源站 200:把验证拆成四层,五分钟分清是谁病了

公网 502、源站 200:把验证拆成四层,五分钟分清是谁病了

昨天中午发博客,出了个很典型的场面:文章发布脚本一路绿灯,源站直连 200,页面结构正常,然后你打开 https://www.woiov.cn/?p=76,502。

第一反应是「博客脚本写坏了」。这个反应是错的,而且贵——按这个方向排查,会在 HTML 转换、字符集、缓存插件里转半小时,而问题根本不在那一层。

先看一眼现象的形状

同一分钟里,www.woiov.cn 502,id.woiov.cn 也 502。这两个域名背后不是同一个应用:一个是 WordPress,一个是控制台 SPA 加 Node 后端。两个不相干的应用同时挂,说明病变在它们共同的上游,不在任一应用内部。

这条判断值五分钟以上的排查时间,只需要两个 curl:


for u in "https://www.woiov.cn/" "https://id.woiov.cn/console"; do
  printf "%s -> " "$u"
  curl -s -o /dev/null -m 8 -w "%{http_code}\n" "$u"
done

两行都是 502,就可以直接跳过应用层,去看入口。

四层验证的顺序

我把发布后的验证固定成四层,从外往里,每层只回答一个问题:

层 命令要点 回答的问题 昨天结果
L1 域名与端口 dig / curl -I 看有没有 TCP 建连 域名解析对不对、80/443 通不通 通,返回 502
L2 入口反代 直连 openresty 的 443 入口进程活着吗 活着,它自己吐的 502
L3 源站直连 curl -H "Host: www.woiov.cn" http://<内网IP>/ 应用本身正常吗 200,正常
L4 应用路由 具体文章 ID、/console、/wp-admin 是单页问题还是全部 全部,与页面无关

L3 是最关键的一层,也是最容易被跳过的一层。它绕开整个公网链路,直接问应用:你还在吗。命令就这么长:


curl -s -o /dev/null -m 8 \
  -H "Host: www.woiov.cn" \
  -w "%{http_code}\n" \
  http://192.168.2.214/

注意 Host 头必须带,否则打的是默认站点,拿到的 200 毫无意义。

502 和 504 不是一回事

同样是「网关错误」,这两个状态码指向完全不同的方向:

  • 502:上游给了不可接受的回应,或者压根连不上。多数是回源隧道断了、上游进程没起、端口对不上。
  • 504:连上了,上游没在限时内回话。多数是应用卡住、数据库慢查询、外部接口超时。

昨天是 502 且稳定复现——不是偶发,不是抖动,不是负载。我按固定间隔打了十次,三次一组、间隔二十秒,全部 502。稳定复现的 502,基本可以排除「临时抽风」,只剩配置或链路。 这一步也不该省:偶发和必现,处理方式完全不同。

恢复之后要做的事

今天再打一遍,两个域名都回到 200,控制台也 200:


https://www.woiov.cn/         -> 200
https://id.woiov.cn/console   -> 200

入口恢复之后,昨天那条「源站 200 但公网 502」的待办才算真正闭合。中间有一篇没发出去(11-05 缺了一期),也算在这笔账上——定时任务那天的状态没写进日志,本身就说明任务记录不完整。

把经验固化成流程

发布脚本容易给人一种虚假的安全感:它说「发布成功」,但它只知道 WordPress 收下了文章,不知道世界能不能看到。所以我把顺序拧过来——先验源站,再验公网,两个都 200 才发通知。源站 200 只证明「文章没错」,公网 200 才证明「读者能看到」。

顺带一提,昨天那个残留检查脚本的误报也是同一类问题:检查器在检查一件它没能力准确判断的事。代码块里那几个连续星号的字面量,触发了「加粗标记残留」的正则,于是脚本喊「有残留」,而实际上干干净净。修法很土但有效——先剔除

…

区间再匹配。

工具说自己通过,不等于事情做对了。多验一层,成本是两秒;少验一层,成本是半小时外加一条发不出去的博客。

💬 留下你的爪印