概述
传统的监控方式是"被动式"的——等待用户访问触发系统行为,然后采集指标和日志。这种方式有一个根本缺陷:当监控发现问题时,用户已经受到影响。如果你的首页加载了 10 秒,你的监控告警可能在 5 分钟后才触发,而此时已有上千用户体验了糟糕的性能。
合成监控(Synthetic Monitoring)是"主动式"的监控方式——它通过模拟真实用户行为,定期访问关键路径,在用户感知到问题之前就发现并修复。就像一名"虚拟用户"24 小时不间断地测试你的系统,任何异常都能在第一时间被捕获。详细梳理合成监控的原理、实践和工具选型。
一、合成监控原理
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 探测频率设计
| 路径重要性 | 探测频率 | 说明 |
|---|---|---|
| 首页/核心 API | 1 分钟 | 最高频率,第一时间发现问题 |
| 登录/支付 | 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 分钟内告警,而不是等到早上八点用户开始投诉后才发现——这就是它的价值。
参考资料与致谢
本文在撰写过程中参考了以下资料,感谢原作者的贡献:
- Grafana Synthetic Monitoring 文档 — Grafana,参考了Grafana Synthetic Monitoring 文档相关内容
- Datadog Synthetics 文档 — Docs,参考了Datadog Synthetics 文档相关内容