Skip to content
返回运维与 SRE

可用性检查

从多区域轻量 TCP/HTTP ping,以最小成本检测可达性宕机。

为什么

合成事务彻底但贵且慢;可用性检查便宜、快,且回答最重要的问题:"用户能到达我们吗?"5 区域每 10 秒 HTTP GET /health 花几分钱,10 秒内抓住最常见宕机类 — 负载均衡、CDN 或 DNS 故障使站点不可达。它们是你监控栈的地板:每个服务都该有一个,无论其余埋点多复杂。没有可用性检查,你最尴尬的宕机就是站点挂了你从客户推文才知道。

何时使用

每个公开端点,第一天。这是第一个要加的监控信号,在仪表盘、RUM、其他一切之前。

如何做

1. 每个服务定义存活端点
   - GET /health 返回 200 + {"status":"ok"} 不检查依赖(快,<10ms)
   - GET /ready 仅当服务能服务真实流量时返回 200(DB 已连)— 用于发布,非可用性

2. 从 3+ 外部区域配置检查
   - HTTP(S) 检查 /health,10 秒节奏,5 秒超时
   - 区域:至少 3 大洲(如美、欧、亚)
   - 用第三方(UptimeRobot/Pingdom/Better Stack)— 非你自己的云

3. 2+ 区域连续 2 次失败才告警
   - 单区域失败 = 探针问题,非宕机 → 工单,不 page
   - 2+ 区域失败 = 站点真挂了 → 立即 page

4. 把告警接到归属团队带 runbook
   - 告警含:URL、失败区域、最后 200 时间戳、runbook 链接
   - 首个失败区域 60 秒内 page(10 秒节奏 × 2 + 评估)

5. 把可用性作为 SLI 跟踪并对外报告
   - "28 天 99.95% 可用性" = SLI;燃烧错误预算则告警
   - 发布状态页(status.example.com)让客户看到同一数字

示例

# /health — 存活(无依赖,永远快)
app.get('/health', (req, res) => res.json({ status: 'ok' }));

# /ready — 就绪(检查依赖,负载均衡用)
app.get('/ready', async (req, res) => {
  try { await db.ping(); res.json({ status: 'ready' }); }
  catch { res.status(503).json({ status: 'not_ready' }); }
});

# UptimeRobot 配置(3 区域,10 秒节奏):
#   监控类型:HTTP(s),关键字:"ok"
#   间隔:10s,超时:5s
#   告警:2 次失败 → @oncall-payments(PagerDuty)
# SLI:可用性 = (总秒数 - 宕机秒数) / 总秒数 ≥ 0.9995 over 28d

常见问题

  • ⚠检查 /ready(含依赖)而非 /health — 依赖打嗝把服务标记为宕机,尽管它仍能服务大部分流量。
  • ⚠从你自己的云跑检查器 — 你云区域宕机时检查器也挂,你漏掉要检测的宕机。
  • ⚠单次失败就 page — 一次网络打嗝 page 值班;要求连续 2 次失败确认真实宕机。
  • ⚠无状态页 — 客户在 Twitter 报宕机先于你团队知道;公开状态页建信任并减支持负载。

最佳实践

  • ✓分离 /health(存活、无依赖、永远快)与 /ready(就绪、检查依赖)— 可用性检查打 /health 使依赖打嗝不误报。
  • ✓从第三方 3+ 区域 10 秒节奏运行;仅 2+ 区域失败才 page 以消除单探针噪声。
  • ✓发布由同一可用性数据驱动的公开状态页 — 宕机期间入站支持工单减约 60%。
  • ✓把可用性作为带错误预算的 SLI 跟踪并月度复盘 — 若在烧预算,在打破 SLO 的月份之前投资可靠性。