技术 •
从 Notion 崩溃到 Astro+CF 纯静态秒开:个人博客内核重构与踩坑全纪实
记录一次将挂掉的 Notion 动态博客重构为 Astro SSG + Keystatic + Cloudflare Pages 的完整实战。包含为什么不用 GitHub 存音频的架构推演,以及 3 个实打实的部署避坑细节。
从 Notion 崩溃到 Astro+CF 纯静态秒开:个人博客内核重构与踩坑全纪实
1. 背景与痛点:为什么旧博客会暴毙?
之前的个人博客(挂载在二级域名 blog.goldenhoversnet.dpdns.org 上)突然无法访问。排查下来,根因是原方案严重依赖外部动态拉取与第三方中转(如 Notion API / 动态渲染脚本)。
这类基于外部 SaaS 数据库的轻量博客方案虽然刚开始建站省事,但存在几个致命的架构脆弱点:
- API 鉴权与 Schema 极脆弱:第三方平台接口稍有变动、Token 过期或匿名请求频率超标(Rate Limit),前台立刻暴毙白屏;
- 多层网络链路衰减:访客 ➔ CDN ➔ 中转 Worker ➔ Notion 数据库,首屏加载存在明显的冷启动和网络等待;
- 数据主权不在手:一旦接口失效,连排版带文章直接失联。
因此,今天决定彻底换掉博客内核:重构为现代纯静态生成(SSG)体系,结合可视化本地写作后台,并托管于 Cloudflare Pages 全球 CDN。
2. 架构推演与技术选型
2.1 为什么是 Astro + Keystatic?
重构的目标很明确:前台必须快、架构必须抗造、零数据库维护成本、随时想写就写。
| 备选方案 | 优点 | 缺点 | 结论 |
|---|---|---|---|
| WordPress / Ghost | 功能大而全,后台成熟 | 必须常驻一台 VPS 服务器和 MySQL,维护繁琐且消耗机器资源 | ❌ 过于笨重 |
| 纯静态 Hexo / Hugo | 编译快、纯静态极速 | 缺少可视化后台,必须在代码编辑器里写,排版不够直观 | ⚠️ 写作体验不够丝滑 |
| Astro + Keystatic (最终选型) | 前台纯静态零 JS 负担,自带类 Notion 的富文本/Markdown 编辑后台 | 本地需 Node 环境支撑开发后台 | ✅ 最佳平衡:前台极速 + 本地可视化写作 |
2.2 延伸推演:为什么音频资源不能学大肥鱼存 GitHub?
在讨论架构时,我们还研判了另一个开源站点「蓝色大肥鱼(bluedafeiyu)」,探讨是否能将游戏 Mod(《杀戮尖塔 2》联机音乐 DJ)的几百兆音频顺便从 Cloudflare 迁到 GitHub 仓库?
实测推演结论:绝对不行!
- 单体体积与 Git 膨胀:
- 大肥鱼存的是表情包图片(单张 100~300KB),Git 处理增量极轻;
- 音乐文件动辄 3
30MB,Git 追踪大体积二进制文件会导致仓库瞬间膨胀数个 GB,极易触发 GitHub 12GB 限制警告甚至封号。
- 国内网络连通性是致命伤:
raw.githubusercontent.com在国内被严重的 DNS 污染与防火墙阻断。实测直接拉取全部超时;若换到 GitHub,国内 Mod 玩家进游戏将 100% 下载失败;- 相反,Cloudflare Pages 原生支持音频 HTTP Range Requests(分片串流),全国节点分发速度与稳定性远超 GitHub。
3. 核心实现架构
flowchart LR
subgraph 本地写作端
A[双击 start.bat] --> B[Astro Local Dev: 4321]
B --> C[Keystatic 可视化后台 /keystatic]
C -->|拖拽传图/排版保存| D[本地 src/content/posts/*.md]
end
subgraph 编译与云端交付
D --> E[双击 deploy.bat]
E --> F[Astro SSG 纯静态构建 dist/]
F --> G[Wrangler 增量推送]
G --> H[Cloudflare Pages: goldenhovers-blog]
H --> I[https://goldenhovers-blog.pages.dev]
end
I -.->|双向互通| J[🎮 贪吃蛇小游戏主站]
为了让平时写作和部署彻底摆脱繁杂命令,我们封装了双击即用的环境:
start.bat:一键拉起本地开发服务,自动打开前台与 Keystatic 后台;deploy.bat:一键调用npm run build预编译 9 个静态页面,并使用 Wrangler 增量推送到 Cloudflare 边缘节点。
4. 真实排错实录(血泪避坑三则)
在初次执行 deploy.bat 上线时,我们遇到了 3 个非常典型但极具隐蔽性的问题:
4.1 坑点一:Wrangler 探测 Cloudflare 账号超时
- 现象:
X [ERROR] Failed to automatically retrieve account IDs for the logged in user. - 根因分析: 在配置了系统代理的机器上,Wrangler 尝试自动调用 Cloudflare API 检索绑定的多账号列表时触发了鉴权超时。
- 解决方案:
无需每次网络探测,直接在
deploy.bat中注入固定的环境变量:set "CLOUDFLARE_ACCOUNT_ID=b441e937fb951e1493b55adb3d4ecb3a"
4.2 坑点二:云端 Pages 专属项目未初始化 (Code: 8000007)
- 现象:
X [ERROR] A request to the Cloudflare API failed: Project not found [code: 8000007] - 根因分析:
账户此前只有用于主站的
my-first-site项目,全新的goldenhovers-blog在云端不存在,直接pages deploy会被拒绝。 - 解决方案:
先执行一次项目初始化指令:
随后即可无缝增量部署。wrangler pages project create goldenhovers-blog --production-branch=master
4.3 坑点三:Keystatic 默认生成 .mdoc 导致 Astro 路由丢失
- 现象: 在后台新建文章并保存后,运行编译只输出了原有页面,新文章完全没有生成对应 HTML。
- 根因分析:
Keystatic 默认的
fields.document生成的是 Markdoc 格式(.mdoc),而 Astro 默认只为.md和.mdx生成静态集合路由。 - 解决方案:
修改
keystatic.config.mjs,显式指定编辑器输出格式为标准.md:
修改后,文章完美被识别,秒级渲染出静态详情页。content: fields.markdoc({ label: '正文内容', extension: 'md', options: { /* 图片目录与常用排版配置 */ } })
5. 验收成果与后续规划
- 秒开与零成本:构建耗时仅 2.76 秒,生成 9 个纯静态页面并秒级推送至全球 CDN,访问延迟从数百毫秒压缩到数十毫秒;
- 主站无缝互联:贪吃蛇小游戏主页(
goldenhoversnet.dpdns.org)右上角直达新博客,博客顶部一键回切小游戏; - 数据百分之百属于自己:全站所有博文均以标准 Markdown 存储在本地 Git 仓库,彻底告别外部 API 崩溃的恐慌。
后续演进建议:
后续若有在手机端随手发文的高频需求,可将本地仓库推送至 GitHub,打通基于 GitHub 授权的无服务器移动端发文链路。目前基于本地 start.bat + deploy.bat 的离线安全流已完全满足日常深度创作需求!