概述

传统的监控方式是"被动式"的——等待用户访问触发系统行为,然后采集指标和日志。这种方式有一个根本缺陷:当监控发现问题时,用户已经受到影响。如果你的首页加载了 10 秒,你的监控告警可能在 5 分钟后才触发,而此时已有上千用户体验了糟糕的性能。

合成监控(Synthetic Monitoring)是"主动式"的监控方式——它通过模拟真实用户行为,定期访问关键路径,在用户感知到问题之前就发现并修复。就像一名"虚拟用户"24 小时不间断地测试你的系统,任何异常都能在第一时间被捕获。详细梳理合成监控的原理、实践和工具选型。

参考来源:Grafana Synthetic Monitoring 文档Datadog Synthetics 文档

一、合成监控原理

1.1 什么是合成监控

合成监控通过预定义的脚本或配置,模拟用户行为(打开页面、点击按钮、提交表单、调用 API),定期执行并记录结果:

┌──────────────────────────────────────────────────────┐
│                合成监控工作流程                         │
│                                                      │
│  ┌──────────────┐                                   │
│  │ 探测节点集群   │  ← 全球分布的探测节点               │
│  │ (Beijing/    │                                   │
│  │  Shanghai/   │                                   │
│  │  Overseas)   │                                   │
│  └──────┬───────┘                                   │
│         │                                            │
│         │ 定时执行探测脚本                              │
│         ▼                                            │
│  ┌──────────────┐    ┌──────────────┐              │
│  │  模拟用户行为  │ ──→ │  目标系统     │              │
│  │  • 打开页面   │    │  (Web/API)   │              │
│  │  • 点击按钮   │    └──────┬───────┘              │
│  │  • 填写表单   │           │                      │
│  │  • 调用 API   │           │                      │
│  └──────┬───────┘           │                      │
│         │                    │                      │
│         ▼                    │                      │
│  ┌──────────────┐           │                      │
│  │  记录结果     │ ←─────────┘                      │
│  │  • 状态码     │                                  │
│  │  • 响应时间   │                                  │
│  │  • 页面内容   │                                  │
│  │  • 截图       │                                  │
│  │  • Trace     │                                  │
│  └──────┬───────┘                                  │
│         │                                            │
│         ▼                                            │
│  ┌──────────────┐                                   │
│  │  告警 + 仪表盘│                                   │
│  └──────────────┘                                   │
└──────────────────────────────────────────────────────┘

1.2 合成监控 vs 被动监控

维度被动监控合成监控
发现方式用户触发后采集主动模拟探测
发现时机问题已影响用户问题影响用户前
覆盖范围有用户访问的路径所有关键路径(含低频路径)
用户视角间接(从指标推断)直接(模拟真实行为)
环境要求需要真实流量无需真实流量
适合场景日常监控关键路径保障、预发验证
成本低(复用已有监控)中(需探测节点和脚本)

1.3 互补关系

被动监控和合成监控互补:

被动监控:
  → 回答"系统现在的状态是什么?"
  → CPU 80%、QPS 1000、错误率 0.1%
  → 发现已有问题的症状

合成监控:
  → 回答"用户能否正常使用?"
  → 首页可访问?登录功能正常?支付流程通畅?
  → 在用户之前发现问题

两者结合 = 完整的可用性保障

二、关键路径模拟

2.1 什么是关键路径

关键路径是用户完成核心业务所必须经过的路径,这些路径一旦中断,直接影响业务收入:

电商网站关键路径:

1. 首页访问 → 页面加载 < 3s
2. 商品搜索 → 搜索结果 < 2s
3. 商品详情 → 页面渲染 < 2s
4. 加入购物车 → API 响应 < 1s
5. 结算流程 → 全流程 < 10s
6. 支付完成 → 支付回调 < 5s

每一步都是关键路径,任何一步出问题都会影响转化率。

2.2 关键路径探测脚本

API 路径探测

# API 合成监控(Checkly / Grafana Synthetics)
steps:
  - name: "用户登录"
    request:
      url: https://api.example.com/auth/login
      method: POST
      headers:
        Content-Type: application/json
      body:
        email: synthetic@test.com
        password: ${SECRET_PASSWORD}
    assertions:
      - status_code == 200
      - response_time < 2000
      - body.token != null

  - name: "获取用户信息"
    request:
      url: https://api.example.com/user/profile
      method: GET
      headers:
        Authorization: Bearer {{steps[0].body.token}}
    assertions:
      - status_code == 200
      - response_time < 1000

  - name: "搜索商品"
    request:
      url: https://api.example.com/products/search?q=phone
      method: GET
      headers:
        Authorization: Bearer {{steps[0].body.token}}
    assertions:
      - status_code == 200
      - response_time < 2000
      - body.products.length > 0

浏览器路径探测

// Playwright 脚本 — 模拟用户购物流程
const { chromium } = require('playwright');

async function syntheticTest() {
    const browser = await chromium.launch();
    const page = await browser.newPage();

    try {
        // 步骤 1:访问首页
        await page.goto('https://www.example.com', { timeout: 10000 });
        await page.waitForLoadState('networkidle');
        const pageTitle = await page.title();
        assert(pageTitle.includes('商城'), '首页标题正确');

        // 步骤 2:搜索商品
        await page.fill('#search-box', '手机');
        await page.click('#search-button');
        await page.waitForSelector('.product-list .product-item', { timeout: 5000 });

        const productCount = await page.locator('.product-item').count();
        assert(productCount > 0, '搜索结果不为空');

        // 步骤 3:点击商品详情
        await page.click('.product-item:first-child');
        await page.waitForSelector('.product-detail', { timeout: 5000 });

        // 步骤 4:加入购物车
        await page.click('#add-to-cart');
        await page.waitForSelector('.cart-success', { timeout: 3000 });

        // 步骤 5:进入结算
        await page.click('#checkout');
        await page.waitForURL('**/checkout/**', { timeout: 5000 });

        console.log('✓ 合成监控通过:购物流程正常');
        await page.screenshot({ path: 'success.png' });

    } catch (error) {
        console.error('✗ 合成监控失败:', error.message);
        await page.screenshot({ path: 'failure.png' });
        throw error;
    } finally {
        await browser.close();
    }
}

module.exports = syntheticTest;

2.3 探测频率设计

路径重要性探测频率说明
首页/核心 API1 分钟最高频率,第一时间发现问题
登录/支付5 分钟关键业务路径
搜索/列表5 分钟高频使用路径
个人中心/设置15 分钟中频路径
低频功能30-60 分钟定期验证可用性

注意:探测频率需要在"发现速度"和"成本/负载"之间平衡。过于频繁的探测会增加后端负载,还可能影响真实用户的性能数据(如 A/B 测试数据被污染)。

三、与被动监控互补

3.1 互补场景

场景被动监控合成监控互补价值
首次部署验证无法验证(无流量)✓ 可验证上线前确认可用
低频功能有流量才采集✓ 定期验证覆盖长尾路径
灾备切换切换后才有流量✓ 主动验证切换前确认
DNS 配置变更无法感知 DNS 问题✓ 能感知发现 DNS 故障
CDN 缓存问题看不到 CDN 层✓ 从 CDN 边缘探测发现缓存异常
SSL 证书过期无法提前发现✓ 提前发现避免证书过期
多地域可用性只看到有流量的地域✓ 全球探测发现地域性问题
性能回归依赖真实用户数据✓ 持续基线早期发现性能下降

3.2 监控分层

┌─────────────────────────────────────────────────────┐
│                   监控分层模型                        │
│                                                     │
│  Layer 4: 合成监控 (主动)                            │
│  → 模拟用户行为,发现"用户能否使用"                    │
│  → 在用户之前发现问题                                 │
│                                                     │
│  Layer 3: 被动监控 (Metrics)                        │
│  → 采集系统指标,发现"系统是否健康"                    │
│  → 实时反映系统状态                                   │
│                                                     │
│  Layer 2: 日志监控 (Logs)                           │
│  → 搜索日志内容,发现"出了什么问题"                    │
│  → 提供排障证据                                      │
│                                                     │
│  Layer 1: 链路追踪 (Traces)                         │
│  → 追踪请求路径,发现"问题在哪里"                      │
│  → 精确定位故障点                                    │
└─────────────────────────────────────────────────────┘

3.3 从合成监控到故障定位

合成监控发现首页响应慢(> 5s)
查看合成监控的 Trace 信息
    ├── DNS 解析 0.5s (正常)
    ├── TCP 连接 0.2s (正常)
    ├── TLS 握手 0.3s (正常)
    ├── 服务端处理 3.5s (异常!)
    └── 页面渲染 0.5s (正常)
跳转到链路追踪(通过 TraceID 关联)
    ├── API Gateway: 0.1s
    ├── User Service: 0.2s
    ├── Product Service: 2.8s ← 瓶颈!
    │   └── Database Query: 2.5s ← 根因!
    └── Cart Service: 0.3s
查看 Product Service 日志
    └── 发现慢查询: SELECT * FROM products WHERE ...
修复:添加索引 / 优化 SQL

四、多地域探测

4.1 为什么需要多地域

单地域探测的盲区:

探测节点在北京
  → 北京访问正常 ✓
  → 上海用户可能无法访问 ✗(看不到)
  → 广州用户可能访问慢 ✗(看不到)
  → 海外用户可能 DNS 解析错误 ✗(看不到)

多地域探测:

探测节点在北京、上海、广州、海外
  → 北京访问正常 ✓
  → 上海访问正常 ✓
  → 广州发现延迟 > 3s ⚠️
  → 海外发现 DNS 解析失败 🔴
  → 每个地域的用户体验都被覆盖

4.2 多地域探测架构

┌─── 北京探测节点 ──────────┐
│  API 测试 + 浏览器测试      │
│  → 探测全国入口             │
└──────────────────────────┘

┌─── 上海探测节点 ──────────┐
│  API 测试 + 浏览器测试      │
│  → 探测华东入口             │
└──────────────────────────┘

┌─── 广州探测节点 ──────────┐
│  API 测试 + 浏览器测试      │
│  → 探测华南入口             │
└──────────────────────────┘

┌─── 海外探测节点 ──────────┐
│  API 测试 + 浏览器测试      │
│  → 探测海外入口             │
└──────────────────────────┘

  ┌──────────────┐
  │  集中存储     │
  │  (Prometheus)│
  └──────┬───────┘
  ┌──────────────┐
  │   Grafana    │
  │  多地域对比   │
  └──────────────┘

4.3 多地域告警策略

groups:
  - name: synthetic-multi-region
    rules:
      # 所有地域都失败 → critical
      - alert: SyntheticAllRegionsDown
        expr: |
          count by(target) (synthetic_probe_success == 0) >= 4          
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "所有地域探测失败: {{ $labels.target }}"
          description: "4 个地域同时探测失败,服务可能完全不可用"

      # 多数地域失败 → critical
      - alert: SyntheticMostRegionsDown
        expr: |
          count by(target) (synthetic_probe_success == 0) >= 3          
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "多数地域探测失败: {{ $labels.target }}"

      # 单地域失败 → warning
      - alert: SyntheticSingleRegionDown
        expr: |
          synthetic_probe_success == 0
          and on(target)
          count by(target) (synthetic_probe_success == 0) < 3          
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "单地域探测失败: {{ $labels.target }} ({{ $labels.region }})"
          description: "仅 {{ $labels.region }} 探测失败,可能是区域网络问题"

      # 地域间延迟差异过大
      - alert: SyntheticLatencyVariance
        expr: |
          (max by(target) (synthetic_probe_duration_seconds) -
           min by(target) (synthetic_probe_duration_seconds)) > 3          
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "地域间延迟差异过大: {{ $labels.target }}"
          description: "最快与最慢地域延迟差异超过 3 秒"

五、UI 自动化测试集成

5.1 与 CI/CD 集成

合成监控的脚本可以同时用于 CI/CD 流水线中的测试:

# GitHub Actions 集成合成监控
name: Synthetic Monitoring

on:
  schedule:
    - cron: '*/5 * * * *'  # 每 5 分钟执行
  workflow_dispatch:        # 手动触发

jobs:
  synthetic-test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        region: [beijing, shanghai, guangzhou]
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm install playwright @playwright/test

      - name: Run synthetic test
        env:
          REGION: ${{ matrix.region }}
          BASE_URL: ${{ vars[format('BASE_URL_{0}', matrix.region)] }}
        run: node synthetic-tests/critical-path.js

      - name: Upload screenshots on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: failure-screenshots-${{ matrix.region }}
          path: screenshots/

5.2 Playwright 合成监控脚本

// synthetic-tests/critical-path.js
const { chromium } = require('playwright');
const { PrometheusPushgateway } = require('prom-client');

const pg = new PrometheusPushgateway('http://pushgateway:9091');

async function runSyntheticTest() {
    const startTime = Date.now();
    const browser = await chromium.launch({
        args: ['--no-sandbox']
    });

    let success = 1;
    let errorMessage = '';

    try {
        const page = await browser.newPage();

        // 注入性能监控
        await page.route('**/*', async (route) => {
            const response = await route.fetch();
            const timing = Date.now() - startTime;
            console.log(`${route.request().url()}: ${response.status()} (${timing}ms)`);
            route.fulfill({ response });
        });

        // 步骤 1:访问首页
        const homeStart = Date.now();
        await page.goto(process.env.BASE_URL, { timeout: 15000 });
        await page.waitForLoadState('networkidle');
        const homeDuration = (Date.now() - homeStart) / 1000;

        if (homeDuration > 3) {
            throw new Error(`首页加载过慢: ${homeDuration}s`);
        }

        // 步骤 2:验证关键元素
        const heroSection = await page.$('.hero-section');
        if (!heroSection) {
            throw new Error('首页关键元素缺失');
        }

        // 步骤 3:测试搜索功能
        const searchStart = Date.now();
        await page.fill('#search-input', 'test product');
        await page.click('#search-submit');
        await page.waitForSelector('.search-results', { timeout: 5000 });
        const searchDuration = (Date.now() - searchStart) / 1000;

        if (searchDuration > 2) {
            throw new Error(`搜索响应过慢: ${searchDuration}s`);
        }

        console.log('✓ 合成监控全部通过');

    } catch (error) {
        success = 0;
        errorMessage = error.message;
        console.error('✗ 合成监控失败:', errorMessage);

        // 截图保存
        const page = await browser.newPage();
        await page.goto(process.env.BASE_URL);
        await page.screenshot({ path: `screenshots/failure-${Date.now()}.png` });
    } finally {
        await browser.close();
    }

    // 推送指标到 Prometheus
    const duration = (Date.now() - startTime) / 1000;
    await pg.pushAdd({
        synthetic_probe_success: {
            value: success,
            labels: {
                target: process.env.BASE_URL,
                region: process.env.REGION
            }
        },
        synthetic_probe_duration_seconds: {
            value: duration,
            labels: {
                target: process.env.BASE_URL,
                region: process.env.REGION
            }
        }
    });

    if (success === 0) {
        process.exit(1);
    }
}

runSyntheticTest();

六、工具选型

6.1 工具对比

工具类型探测方式多地域浏览器测试成本适合场景
Grafana Synthetic Monitoring开源API + 浏览器✓ 全球节点✓ Playwright低(需 Grafana Cloud)已有 Grafana 生态
Blackbox Exporter开源API + TCP + ICMP需自建节点免费基础 API/网络探测
Checkly商业API + 浏览器✓ 全球节点✓ Playwright专注合成监控
Datadog Synthetics商业API + 浏览器✓ 全球节点已用 Datadog
Pingdom商业API + 浏览器✓ 全球节点简单拨测
New Relic Synthetics商业API + 浏览器✓ 全球节点已用 New Relic
k6 + k6 Cloud开源/商业API性能测试 + 合成监控

6.2 Grafana Synthetic Monitoring

Grafana Synthetic Monitoring 是 Grafana Cloud 提供的合成监控服务,基于 Prometheus 和 Playwright:

# Grafana Synthetic Monitoring 配置
probes:
  - id: probe-us-east
    region: us-east-1
  - id: probe-eu-west
    region: eu-west-1
  - id: probe-ap-south
    region: ap-south-1

checks:
  - name: "Homepage HTTP"
    type: HTTP
    config:
      url: https://www.example.com
      method: GET
      headers:
        User-Agent: "Grafana-Synthetic"
    assertions:
      - status_code == 200
      - response_time < 3000
    frequency: 60s
    probes: [probe-us-east, probe-eu-west, probe-ap-south]

  - name: "Login API"
    type: HTTP
    config:
      url: https://api.example.com/auth/login
      method: POST
      body: '{"email":"test@example.com","password":"***"}'
    assertions:
      - status_code == 200
      - response_time < 2000
    frequency: 300s
    probes: [probe-us-east, probe-eu-west]

  - name: "Checkout Flow"
    type: Browser
    config:
      script: |
        await page.goto('https://www.example.com');
        await page.fill('#search', 'phone');
        await page.click('#search-btn');
        await page.waitForSelector('.product-item');
        await page.click('.product-item:first-child #add-to-cart');
        await page.waitForSelector('.cart-success');        
    frequency: 600s
    probes: [probe-us-east]

6.3 Blackbox Exporter 作为轻量合成监控

对于不需要浏览器测试的场景,Blackbox Exporter 可以作为轻量级合成监控:

# Prometheus 配置 — Blackbox 作为合成监控
scrape_configs:
  - job_name: 'synthetic-api'
    metrics_path: /probe
    params:
      module: [http_2xx]
    static_configs:
      - targets:
          - https://www.example.com              # 首页
          - https://api.example.com/health        # API 健康检查
          - https://api.example.com/v1/products   # 商品 API
        labels:
          synthetic: 'true'
          type: 'api'
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: blackbox:9115

6.4 工具选型决策

你的合成监控需求是什么?

只需要 API/TCP 拨测?
  ├── 是 → Blackbox Exporter(免费,够用)
  └── 否 → 需要浏览器测试?

需要浏览器测试?
  ├── 是 → 已有 Grafana 生态?
  │         ├── 是 → Grafana Synthetic Monitoring
  │         └── 否 → Checkly(专注,性价比好)
  └── 否 → 只需要 API 拨测 + 全球节点?
            ├── 是 → Pingdom(简单可靠)
            └── 否 → 已有 Datadog/New Relic?
                      ├── 是 → 用平台自带 Synthetics
                      └── 否 → Grafana Synthetic Monitoring

七、可用性 SLO 度量

7.1 基于合成监控的 SLO

# 可用性 SLO(30 天窗口)
avg_over_time(synthetic_probe_success[30d]) * 100

# 按目标和地域
avg by(target, region) (avg_over_time(synthetic_probe_success[30d])) * 100

# 响应时间 SLO
histogram_quantile(0.95,
  sum by(le, target) (rate(synthetic_probe_duration_seconds_bucket[5m]))
)

# 成功率趋势
avg_over_time(synthetic_probe_success[1h]) * 100

7.2 SLO 告警

groups:
  - name: synthetic-slo
    rules:
      # 可用性 SLO 违约(30 天 < 99.9%)
      - alert: SyntheticAvailabilitySLOBreach
        expr: |
          avg by(target) (avg_over_time(synthetic_probe_success[30d])) < 0.999          
        for: 5m
        labels:
          severity: warning
          slo: availability-999
        annotations:
          summary: "合成监控可用性 SLO 违约: {{ $labels.target }}"
          description: "近 30 天可用性低于 99.9%"

      # 响应时间 SLO 违约(P95 > 3s)
      - alert: SyntheticLatencySLOBreach
        expr: |
          histogram_quantile(0.95,
            sum by(le, target) (rate(synthetic_probe_duration_seconds_bucket[5m]))
          ) > 3          
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "合成监控延迟 SLO 违约: {{ $labels.target }}"
          description: "P95 响应时间超过 3 秒"

八、生产实践

8.1 探测脚本管理

synthetic-tests/
├── api/
│   ├── health-check.js        # API 健康检查
│   ├── auth-flow.js           # 登录流程
│   ├── product-search.js      # 商品搜索
│   └── checkout-flow.js       # 结算流程
├── browser/
│   ├── homepage.js            # 首页加载
│   ├── search-and-buy.js     # 搜索到购买全流程
│   └── mobile-responsive.js   # 移动端适配
├── config/
│   ├── environments.json      # 环境配置
│   └── thresholds.json        # 阈值配置
└── lib/
    ├── prometheus.js          # 指标推送
    └── alerting.js            # 告警逻辑

8.2 探测数据隔离

合成监控产生的流量和日志应该与真实用户数据隔离:

# 在应用中识别合成监控流量
# 方式 1:特殊 User-Agent
headers:
  User-Agent: "Synthetic-Monitor/1.0"

# 方式 2:特殊 Header
headers:
  X-Synthetic-Monitor: "true"
  X-Synthetic-Test-ID: "checkout-flow-001"

# 方式 3:专用测试账号
auth:
  email: synthetic-monitor@example.com
  password: ${SYNTHETIC_PASSWORD}

在应用中过滤合成监控数据:

// 排除合成监控流量
if (request.getHeader("X-Synthetic-Monitor") != null) {
    // 不计入业务指标
    // 不写入业务日志
    // 不触发 A/B 测试
}

8.3 探测结果可视化

┌─────────────────────────────────────────────────────────┐
│              合成监控仪表盘                                │
│                                                         │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐             │
│  │ 总探测数  │  │ 成功率    │  │ 平均延迟  │             │
│  │   8,640  │  │  99.5%   │  │  1.2s    │             │
│  └──────────┘  └──────────┘  └──────────┘             │
│                                                         │
│  ┌─────────────────────────────────────────────┐       │
│  │  各路径成功率(30 天趋势)                    │       │
│  │  首页     ━━━━━━━━━━━━━━━━━━ 100%           │       │
│  │  搜索     ━━━━━━━━━━━━━━━━━━ 99.8%          │       │
│  │  登录     ━━━━━━━━━━━━━━━━━━ 99.5%          │       │
│  │  结算     ━━━━━━━━━━━━━━━━━━ 98.2% ⚠️       │       │
│  │  支付     ━━━━━━━━━━━━━━━━━━ 99.9%          │       │
│  └─────────────────────────────────────────────┘       │
│                                                         │
│  ┌─────────────────────────────────────────────┐       │
│  │  多地域延迟对比                                │       │
│  │  北京  ━━━━━━━━━━━━ 0.8s                    │       │
│  │  上海  ━━━━━━━━━━━━━━ 1.0s                  │       │
│  │  广州  ━━━━━━━━━━━━━━━━━━ 1.5s              │       │
│  │  海外  ━━━━━━━━━━━━━━━━━━━━━━━━ 2.5s ⚠️   │       │
│  └─────────────────────────────────────────────┘       │
│                                                         │
│  ┌──────────────────────┐ ┌──────────────────────┐    │
│  │ 最近失败的探测         │ │ SSL 证书到期           │    │
│  │ Target | Time | Error│ │ 域名 | 剩余天数        │    │
│  └──────────────────────┘ └──────────────────────┘    │
└─────────────────────────────────────────────────────────┘

九、好的实践

9.1 探测脚本设计原则

原则说明
独立于真实数据使用专用测试账号和测试数据
可复现脚本可重复执行,结果一致
快速失败超时设置合理,不长时间等待
有意义的断言验证关键内容,而非只检查状态码
分层设计API 测试 + 浏览器测试分层
数据隔离不影响真实用户数据和业务指标

9.2 告警设计

# 分级告警
- alert: SyntheticAPIFailure
  expr: synthetic_probe_success{type="api"} == 0
  for: 1m
  labels:
    severity: critical
  annotations:
    summary: "API 探测失败: {{ $labels.target }}"

- alert: SyntheticBrowserFailure
  expr: synthetic_probe_success{type="browser"} == 0
  for: 3m   # 浏览器测试允许更多重试时间
  labels:
    severity: warning
  annotations:
    summary: "浏览器探测失败: {{ $labels.target }}"

- alert: SyntheticLatencyDegradation
  expr: |
    avg_over_time(synthetic_probe_duration_seconds[1h]) >
    2 * avg_over_time(synthetic_probe_duration_seconds[7d])    
  for: 15m
  labels:
    severity: warning
  annotations:
    summary: "响应时间退化: {{ $labels.target }}"
    description: "当前延迟是过去 7 天平均值的 2 倍以上"

9.3 常见误区

误区正确做法
探测过于频繁导致后端压力根据路径重要性设置合理频率
只检查状态码不检查内容验证关键内容和业务逻辑
忽略探测脚本维护脚本随业务变化更新
合成监控替代被动监控两者互补,不可替代
不隔离探测数据用特殊 Header/账号标记探测流量
单地域探测多地域探测覆盖所有用户来源

总结

合成监控是可观测性体系的重要补充,它的核心价值在于"主动"和"用户视角":

  • 主动发现:在用户感知到问题之前就发现并修复,将影响降到最低
  • 用户视角:模拟真实用户行为,度量用户体验而非系统指标
  • 关键路径保障:对核心业务路径持续验证,确保转化率不受影响
  • 多地域覆盖:从全球不同地域探测,发现地域性网络和 CDN 问题
  • 与被动监控互补:被动监控发现"症状",合成监控发现"用户影响",两者结合形成完整的可用性保障
  • 工具选择务实:简单 API 拨测用 Blackbox Exporter,浏览器测试用 Grafana Synthetic Monitoring 或 Checkly,已用 Datadog 则用其内置 Synthetics

合成监控不是可选项,而是保障用户体验的必要手段。当一个凌晨三点的 DNS 配置变更导致首页无法访问时,合成监控能在 1 分钟内告警,而不是等到早上八点用户开始投诉后才发现——这就是它的价值。

参考资料与致谢

本文在撰写过程中参考了以下资料,感谢原作者的贡献:

  1. Grafana Synthetic Monitoring 文档 — Grafana,参考了Grafana Synthetic Monitoring 文档相关内容
  2. Datadog Synthetics 文档 — Docs,参考了Datadog Synthetics 文档相关内容