Skip to content
返回运维与 SRE

合成监控

从外部探针向生产环境运行脚本化事务,在用户之前发现宕机。

为什么

真实用户监控告诉你发生了什么;合成监控从已知有利位置、按你控制的节奏告诉你此刻正在发生什么。一个每 60 秒登录、加购物车、结账的合成检查会在 60 秒内抓住坏掉的支付网关,而 RUM 可能要等到足够多真实用户命中才让 p95 移动。合成也是监控低流量关键路径的唯一方式 — 你凌晨 3 点的结账流可能每小时只有 2 个真实用户,但合成每分钟都看到它。它们是获得直接映射"站点是否在线"的可用性 SLI 的最便宜方式。

何时使用

服务到生产之后。优先 top 3-5 用户旅程(登录、搜索、结账、注册)。每上线一个新关键路径就加一个检查。

如何做

1. 识别 3-5 个关键用户旅程
   - 登录、搜索、加购物车+结账、注册、关键 API 读
   - 这些是失败 = "站点挂了"对用户而言的路径

2. 把每个旅程脚本化为确定性事务
   - 用 Playwright/Selenium;无头 Chrome;固定测试账号
   - 在最终步骤断言(如"到达订单确认页")
   - 运行时间 <30 秒,使 1 分钟节奏在 2 个周期内抓住宕机

3. 从多个地理位置和提供商运行
   - 3+ 探针(如美东、欧洲、亚洲),使单区域抖动不误报
   - 用第三方(Pingdom/UptimeRobot/Datadog Synthetics),使探针不在你自己的云里

4. 对失败告警,不对慢告警
   - 2+ 区域连续 2 次失败 = page(避免单探针噪声)
   - 延迟退化 = 单独的低优先级工单(不要对慢 page)

5. 每个检查打上旅程和归属团队标签
   - 告警路由到拥有该旅程的团队,而非通用"ops"队列
   - 告警中包含 runbook 链接和最后正常截图

示例

// synthetics/checkout.ts — Playwright 合成检查
import { test, expect } from '@playwright/test';
test('checkout 旅程', async ({ page }) => {
  await page.goto('https://app.example.com/login');
  await page.fill('#email', '[email protected]');
  await page.fill('#password', process.env.SYNTH_PASS!);
  await page.click('button[type=submit]');
  await expect(page).toHaveURL(/dashboard/);
  await page.click('text=Add to cart');
  await page.click('text=Checkout');
  await page.fill('#card', '4242 4242 4242 4242'); // 测试卡
  await page.click('text=Pay');
  await expect(page).toHaveText(/Order confirmed/);
});
// 每 60 秒从 3 个区域经 Datadog Synthetics 运行:
//   节奏:60s,位置:["us1","eu1","ap1"],告警:2 区域各 2 次失败
// 告警载荷含:journey=checkout,team=payments,runbook=https://rb/checkout-down

常见问题

  • ⚠从你自己的 VPC 内跑合成 — 区域云宕机把探针也带挂,于是你漏掉了你要检测的宕机。
  • ⚠单探针失败就 page — 一个抖动浏览器或 DNS 打嗝在凌晨 3 点 page 值班;要求 2+ 区域失败才 page。
  • ⚠用共享测试账号被限流或锁住 — 合成因测试卫生原因开始失败,掩盖真实宕机。
  • ⚠脚本与真实 UI 漂移(选择器过期)— 合成因无害的按钮改名而失败,制造告警疲劳并侵蚀信任。

最佳实践

  • ✓从你云提供商之外的第三方、3+ 区域运行探针,使单区域宕机被检测而非被静音。
  • ✓合成脚本入 Git 随应用版本化,每次部署在 CI 跑 — 选择器变更破坏合成则部署失败。
  • ✓仅 2+ 区域连续 2 次失败才告警;单探针失败路由到低优先级清理队列以保值班理智。
  • ✓告警载荷中含失败截图 — 一张 500 页的图省值班工程师 5 分钟复现。