五分钟的配置,换来十年的"我比用户先知道出了问题"。外部服务每分钟从多个地区向您的网站发送探针;当探针失败时,您会在用户发推吐槽之前收到通知。这是最物美价廉的可靠性工具。
可用性监控和错误追踪听起来相似,但两者并不相同。Sentry 从内部监控您的应用代码——当请求崩溃时,Sentry 捕获异常并告知您。可用性监控则从外部监控您的网站——当服务器完全无法访问时,Sentry 无法通知您,因为 Sentry 自己也连不上服务器。两者相辅相成,缺一不可。本教程介绍后者。
核心原理很简单:外部服务每隔一分钟(或每五分钟,取决于套餐)向您的 URL 发起 HTTPS 请求,检查响应结果,当响应异常时发出告警。"正常"可以是以下任意条件:HTTP 200、响应体中包含特定字符串、响应时间低于 N 毫秒、TLS 证书有效。检测来自多个地理区域,以避免单区域网络问题产生误报。告警通过您选择的渠道送达:电子邮件、短信、Slack、Discord、PagerDuty、手机推送通知。
本教程以 UptimeRobot 为默认选项——其免费套餐能满足大多数个人和小型企业的需求(50 个监控器,5 分钟间隔),界面也确实简洁易用。Better Stack、Pingdom、StatusCake 和 Hyperping 功能相当;本教程的方法对它们同样适用。我们将完成以下内容:创建监控器、设计一个能区分"进程存活"与"数据库可达"的 /health 端点、接入 Slack 通知,以及(可选)搭建一个公开状态页面,让用户在出现问题时能自行查看。
/health 端点——而不只是 res.send("ok")localhost:3000,请先部署——可用性监控需要一个公开端点才能探测。有 Slack 或 Discord 工作区会更方便,但不是必须的;邮件告警默认就能使用。
您可以直接监控首页 URL——对于静态网站来说这没问题。但对于有数据库和依赖服务的应用,首页即使在数据库不可达时也可能返回 200(缓存的 HTML、静态降级页、通用错误页)。专门构建的 /health 端点能区分三个层级:
app.get('/health', (req, res) => res.send('ok'))。适合检测进程崩溃,但无法检测依赖故障。对于可用性监控,就绪检查是最合适的形式:
app.get('/health', async (req, res) => {
try {
await db.query('SELECT 1');
await redis.ping();
res.json({ status: 'ok', db: 'ok', redis: 'ok' });
} catch (err) {
res.status(503).json({ status: 'degraded', error: err.message });
}
});
这样,/health 返回 200 就意味着"进程存活,且依赖可达"——比监控首页提供了更有力的信号。
/health 轻量且无需认证。不要对其设置鉴权(监控器无法完成认证);不要让它执行开销大的查询;不要在它前面加限流。该端点每分钟被多个监控器调用——如果它很慢,您的账单会增加;如果它受到拦截,监控器会误报故障。
前往 uptimerobot.com 注册。免费套餐包含 50 个监控器,5 分钟间隔。(付费 Solo 套餐每月 $7,支持 1 分钟间隔和短信通知。)
进入控制台 → + New Monitor:
https://mybrand.com/health。"ok",类型选"Yes — alert when keyword does not exist"。这样监控器不仅检查 HTTP 状态码,还会核实响应体中是否包含该字符串。那些返回 200 但附带错误信息的页面再也骗不过它了。保存后,监控器会在一分钟内开始探测,响应时间图表随即开始填充数据。
UptimeRobot 控制台 → My Settings → Alert Contacts → Add Alert Contact。每个"联系人"对应一个告警目标:
<workspace>.slack.com/apps 搜索"Incoming Webhooks"→ 选择频道 → 复制 URL。告警会以监控器名称和宕机时长的形式发送到该频道。添加联系人后,编辑监控器并勾选哪些联系人应接收其告警。生产监控器通常同时启用邮件、Slack 和短信;测试环境监控器仅启用邮件。
对每次抖动都发出告警的监控器,最终会沦为背景噪音。三个设置可以改善这一问题:
目标是"每条告警都是真实的,每次真实故障都有告警"。朝任何一个方向偏移都会削弱监控的价值。
状态页面(status.mybrand.com)向用户展示您的服务各部分是否正常运行。出现问题时,用户查看状态页面而不是发邮件给客服。一切正常时,状态页面也是一种信任背书。
对于大多数用户量低于 1 万的项目,UptimeRobot 免费状态页面已经足够。只有当用户开始要求查看故障历史时,再考虑升级。
HTTP 可用性监控只能捕获 HTTP 层面的故障。另一种常见的无声故障是:一个 cron 任务(夜间备份、每周摘要邮件、每小时清理)已经中断两周,却无人知晓。
解决方案:使用 Healthchecks.io(最多 20 个检查项免费)等服务,为每个 cron 任务生成一个唯一 URL。任务每次成功执行后向该 URL 发送探针。如果探针在预期时间内停止到达,Healthchecks 就会发出告警。
# In your cron job script, last line:
curl -fsS --retry 3 https://hc-ping.com/<your-unique-uuid> > /dev/null
# In crontab:
0 3 * * * /usr/local/bin/backup.sh && curl -fsS https://hc-ping.com/<uuid>
Healthchecks 知晓预期的执行计划(您自行配置),并在探针超期时通知您。这对备份任务尤为有用——"备份是否执行"这个问题,往往只有在需要还原数据的那一天才会被追问。
Vercel / Netlify / Cloudflare Pages 上的静态网站。这些平台的 CDN 可用性接近 100%;如果它们出现宕机,影响范围远超您的网站。添加可用性监控能捕获"您的配置导致构建失败"的情况,但这类问题通常会优先出现在部署日志中。
仅供内部使用、无用户、无营收影响的工具。如果宕机只影响到您自己,且您无论如何都会在一小时内发现,那么监控器及其维护成本就不值得了。
您在接下来 24 小时内无法响应告警。可用性监控最有价值的前提,是有人随时待命响应告警。没有这个条件,告警只会在收件箱里积压。等到您能真正处置凌晨 3 点告警的阶段,再配置监控也不迟。