博客跑起来之后,我心里一直有个小疙瘩:这站到底什么时候是活的?
GitHub Pages 偶尔抽风、构建失败、证书过期,这些都是我控制不了的。但至少我可以知道它出事了,而不是等别人来告诉我。于是我想找个 uptime 监控方案。
要求就三条:不花钱、不用服务器、能挂在博客旁边。搜了一圈,答案指向同一个项目——Upptime。
第一回合:这东西简直是为我量身定做的
Upptime 的自我介绍很讨喜:100% 基于 GitHub Actions 的开源 uptime 监控。翻译成人话就是:
- 不用买服务器:探测任务跑在 GitHub Actions 的免费额度里
- 不用数据库:每次探测的结果,直接写成一个 GitHub Issue
- 状态页就是静态页:托管在 GitHub Pages 上,跟你博客同一个地方
对我这种全站都在 GitHub 上的博客来说,这不叫"合适",这叫"闭环"。
部署也简单得不像话:项目提供模板仓库,点一下 Use this template,生成自己的仓库,改配置文件里的 URL 列表,把要监控的地址填进去。剩下的交给 Actions。
改完配置,我美滋滋地打开自己那份状态页,准备欣赏一下绿色的 UP。
第二回合:页面打开了,但一直在转圈
页面骨架是出来了,标题、表头都在,中间那块本该显示各站点状态的地方——一个转圈的小图标,转啊转,转到我怀疑人生。
第一反应是网慢。刷新,还是转。换个浏览器,还是转。等了五分钟,它依然在转。
这时候我想起一个基本的排错动作:找个正常的参照物。打开 Upptime 的官方 demo 页面——秒开,状态、响应时间、历史曲线,全都在。
一句话诊断:不是网络问题,不是浏览器问题,是我这份实例的问题。
第三回合:抓到那个 An error occurred
转圈转久了,有时候会翻脸,直接甩一句冷冰冰的:
An error occurred
这句话没有任何信息量,但它是条线索——说明前端在某个环节拿不到数据了。于是我打开 F12,切到 Network 面板,刷新页面,看请求列表。
果然,页面加载完之后,有一条请求是去打 GitHub 的 API 的。点开它:
- 状态码:403
- 响应体里有一段 message,提到了 rate limit
到这里,案子破了一半。
第四回合:撞上 GitHub API 的额度墙
Upptime 的原理决定了它绕不开 GitHub API:状态页是一张静态 HTML,它自己不存任何监控数据,每次打开都要实时去 GitHub 拉 Issue 列表,才能渲染出"哪个站 UP、哪个站 DOWN"。
而 GitHub API 对未认证的请求是有额度限制的:同一个 IP 每小时只能请求 60 次。
60 次听起来不少,但状态页一次加载要拉好几个接口——Issue 列表、每个 Issue 的评论、Actions 的运行记录。**也就是说,随手刷新几次、多开几个标签页,就有可能把这小时的额度打光。**额度一满,接口一律返回 403,前端拿不到数据,于是:
- 拿不到数据又没做兜底 → 一直转圈
- 请求直接失败 → An error occurred
那个转圈的小图标,本质上是在说:“我等 data,但 data 永远不会来了。”
第五回合:给它一个身份,把额度从 60 提到 5000
解法其实一直写在 Upptime 的文档里,只是我一开始跳过了:用 token 认证请求。
未认证是 60 次/小时,认证之后是 5000 次/小时——差了将近一百倍。做法是去 GitHub 生成一个 Personal Access Token,用最小权限(读公开仓库的 Issue 就够了,不需要任何写权限),然后把它配置到状态页那边,让前端的请求带上这个 token。
顺手还做了两件事:
- 降低了状态页的自动刷新频率。以前它隔一会儿就自己去拉一次数据,白白消耗额度;现在改成手动刷新或者拉长间隔,够用就行。
- 给 token 记了个到期提醒。PAT 是有有效期的,一旦过期,症状会和现在一模一样——页面又开始转圈。这种"修复过的问题又回来了"最坑人,因为你会以为是新 bug。
改完再打开状态页:数据出来了,绿点一排。
最后唠两句
这次踩坑,真正学到的东西不是"Upptime 怎么配",而是三件更通用的:
一、转圈不是"网慢",先看 Network。 任何前端页面长时间 loading,第一个动作都应该是打开开发者工具,看请求是发出去了没、回来了没、回来的是什么状态码。凭感觉猜"是不是网卡了",纯属浪费时间。
二、免费服务都有隐形的额度墙。 GitHub Actions、GitHub API、各种 Free Tier,没有一个是无限的。搭东西之前先搞清楚"我这次调用算不算额度",能省掉很多莫名其妙。
三、403 的 message 比 403 本身值钱。 状态码只告诉你"不行",message 才会告诉你"为什么不行、什么时候可以再试"。多看一眼响应体,少猜半小时。
现在这块状态页稳稳地挂在旁边,我终于能知道自己的站是死是活了。有点讽刺:一个用来监控别人死活的页面,自己先死了一次。
也算给我上了第一课——监控系统本身,也得有人监控。