我给博客换了链接,然后它挂了一早上

1493 字
7 分钟
我给博客换了链接,然后它挂了一早上
AI 智能总结内容由 AI 生成,仅供参考

博客将链接改为纯数字序号和独立标签页,压缩图片降低约60% 大小;但内部互链未更新,导致死链。凌晨 06:44,nginx 启动时解析 upstream DNS 抖动,Ubuntu 只尝试重启一次,网站连线持续九小时。修复时将 upstream 换为变量+resolver 延迟 DNS,给 systemd 加 RestartSec=5s 自动重启,并配备每分钟运行的看门狗。恢复后数据显示完好,验证了自动监控与恢复的必要性。

这周折腾了两件事,本来不想写成文章,但第二件事实在太有戏剧性——我把博客的链接全部翻新了一遍,第二天凌晨它就挂了九个小时。两件事还挺有因果关系的味道,一起记下来。

一、链接翻新:从「能访问」到「有规律」#

原来的链接有多随意#

先自曝家丑。这个站原来的链接长这样:

文章:/posts/how-i-built-this-blog/
标签:/archive/?tag=%E9%9A%8F%E7%AC%94
分类:/archive/?category=%E6%8A%80%E6%9C%AF

文章 slug 是标题转的英文,长短随缘;标签和分类点开更离谱——%E9%9A%8F%E7%AC%94 这是「随笔」的 URL 编码,一串百分号乱码,别说访客看不懂,搜索引擎对这种查询参数式链接也不太待见:它本质上是归档页的过滤参数,不是独立页面,没有自己的权重。

文章改数字编号#

第一个决定:文章 slug 全部改成纯数字,/posts/1/、/posts/2/,按发布顺序排。理由很简单——短、整齐、永远不重名。缺点是链接没了语义,但对个人博客来说,标题在列表和搜索结果里都有展示,URL 里那点语义没那么值钱。

改的时候给自己挖了个坑:旧链接全部 301 重定向到新地址,这个做了;但文章正文里的互相引用忘了改——三篇技术文互相链接用的还是旧 slug,全站扫描死链的时候才暴露出来。顺手把关于页里一个指向不存在的 /posts/ 的入口也修成了归档页。

教训:改 URL 结构,扫描器跑一遍全站比肉眼靠谱得多。全站 1928 个站内链接,人工根本看不过来。

分类标签建独立页面#

这是更大的一块。原主题根本没有分类详情页,所谓「点标签」就是跳归档页带个过滤参数。这次直接新建了两类静态页面:

分类:/categories/ji-shu/ (技术)
标签:/tags/sui-bi/ (随笔)

slug 的规则:中文转全拼小写,英文原样,短横线分隔。看名字就能拼出 URL,以后打新标签也自动按这个规则生成页面,规律是死的,不会因为手滑打出新格式。

实现上用的是 pinyin-pro(主题本来就带了)在构建期转换,页面静态生成、自动进 sitemap,每个分类和标签从此都有了自己可收录的落地页。

顺手把图压了#

审计图片的时候发现相册里有四张原图是原样发布的:一张 1.5MB 的 PNG、两张快 1MB 的 JPG。全部转成 WebP(质量 85,肉眼无感),整个相册从 4.2MB 降到 1.76MB,减了 58%。

二、宕机九小时:一次教科书级的连锁反应#

链接翻新的第二天凌晨 06<44>,博客挂了。而且不是慢,是完全打不开,一直挂到下午。

时间线还原#

翻了系统日志,链条其实很短:

06:44:05 系统自动安全更新(unattended-upgrade)启动,升级 openssl
06:44:18 openssl 是 nginx 的依赖库 → 触发 nginx 自动重启
06:44:18 重启瞬间 DNS 抖动:配置里的封面代理域名 t.alcy.cc 解析失败
06:44:18 nginx -t 报错:host not found in upstream → 启动失败
(然后呢?然后就没有然后了)

两个问题叠加成了九小时的宕机:

第一,nginx 启动时要解析配置里所有的 upstream 域名。 平时这不是问题,但「启动的那一刻 DNS 抖了一下」就够了——DNS 恢复后配置完全正常,可 nginx 已经躺在那里不会自己爬起来。

第二,nginx 的 systemd 重启策略是 Restart=no。 Ubuntu 的默认值。失败不重试,一次失败就是永久失败。

最讽刺的是:我明明有每分钟跑的监控脚本、有每 5 分钟的部署兜底任务,但没有任何一个东西负责「发现 nginx 挂了就把它拉起来」。监控和数据都在,就差最后一步。

三层修复#

修的时候就没打算只修「这一次」:

第一层,根治启动依赖。 封面代理的 upstream 改成「变量 + resolver」:

resolver 223.5.5.5 119.29.29.29 valid=300s ipv6=off;
set $alcy_upstream "t.alcy.cc";
rewrite ^/cover-proxy/alcy/(.*)$ /$1 break;
proxy_pass https://$alcy_upstream;

用变量做 upstream 时,域名解析推迟到运行时——启动时不再碰 DNS。以后 DNS 再抖,最坏也就是那一次封面图请求 502,nginx 本体稳如泰山。有个小坑:proxy_pass 带变量时不会自动剥离 location 前缀,必须手动 rewrite 补上,不然转发路径就是错的。

第二层,自动拉起。 给 nginx 的 systemd 加了 Restart=on-failure,挂掉 5 秒后自动重试。就算再来一次同样的故障,DNS 恢复的几秒内它就自己站起来了。

第三层,看门狗。 监控脚本旁边加了一个每分钟跑的看门狗:nginx 或后台服务不是 active 就直接拉起,写日志。它不聪明,但足够愣——专治各种「以为它会自己好」。

零损失的安慰#

复盘时最庆幸的一点:宕机的九个小时里没有发布任何内容,最后一次部署停在宕机前一晚,所有数据完好。而且部署兜底任务走的是 cron 直连,根本不经过 nginx——就算那九小时里我发了文章,内容也会照常上线,只是没人看得到而已。

写在最后#

这次折腾完,两件原本不相干的事最后落在了同一个认知上:

「它能跑」和「它挂了我能立刻知道、立刻站起来」是两码事。前者叫功能,后者才叫运维。

链接是给人和搜索引擎看的,规律比个性重要;服务是给凌晨四点的自动更新折腾的,兜底比侥幸重要。文章里如果有你也用得上的东西,欢迎翻翻这个系列的其他几篇——现在它们都在 /posts/1/ 到 /posts/6/ 里,链接干净得很。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

我给博客换了链接,然后它挂了一早上
https://li8.me/posts/8/
作者
八奈奈
发布于
2026-10-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
八奈奈
记录技术与生活
公告
欢迎来到「二次元宅男录」!这里记录技术与生活,欢迎常来逛逛。
分类
标签
站点统计
文章
10
分类
4
标签
18
总字数
17,017
运行时长
0 天
最后活动
0 天前
文章目录