2. 值班环境基线定义:什么是基线、基线指标与偏离判定
在告警降噪体系中,基线(Baseline)是值班环境“正常”与“异常”的分界线。没有基线,告警就失去了比较的参照物,所有波动都会被视为故障。本章将系统定义基线、核心指标以及偏离判定标准,为后续自动化核验打下基础。
2.1 什么是基线
基线是系统在稳定运行周期内,关键性能指标(KPI)的统计分布范围。它不是单一固定值,而是一个包含均值、标准差、百分位数的动态区间。基线通常通过以下方式建立:
- 历史窗口法:取过去 7 天 / 14 天 / 30 天同一时间段的指标数据,计算 P50、P95、P99 作为基线上下界。
- 业务周期法:区分工作日 / 周末、白天 / 夜间、促销期 / 平峰期,分别建立基线。
- 部署版本法:每次代码发布后,重新校准基线,避免旧基线误判新版本行为。
实践要点:基线不是“写死”的阈值,而是随时间、版本、流量模式自动演化的动态区间。建议基线更新周期 ≤ 24 小时。
2.2 核心基线指标
值班环境最关注的三大黄金指标(Google SRE 经典模型)为:延迟(Latency)、错误率(Error Rate)、饱和度(Saturation)。下表给出每个指标的定义、典型度量方式及基线示例:
| 指标 | 定义 | 典型度量 | 基线示例(7天窗口) |
|---|---|---|---|
| 延迟 | 请求从发出到收到完整响应的时间 | P50 / P95 / P99 延迟(ms) | P50 ≤ 200ms, P95 ≤ 800ms, P99 ≤ 2000ms |
| 错误率 | 失败请求占总请求的比例 | HTTP 5xx 占比 / 业务错误码占比 | 错误率 ≤ 0.1%(P99 基线) |
| 饱和度 | 资源使用程度,越接近上限越危险 | CPU 使用率 / 内存使用率 / 连接池占用率 | CPU ≤ 70%, 内存 ≤ 80%, 连接池 ≤ 75% |
指标选择原则:优先选择用户可感知的指标(延迟、错误率),其次选择容量预警指标(饱和度)。避免将内部实现细节(如 GC 次数、线程数)直接作为基线指标,除非它们与用户体验有明确因果关系。
2.3 基线偏离的判定标准
基线偏离不是简单的“超过阈值就告警”,而是需要结合偏离幅度、偏离持续时间、偏离趋势三个维度综合判定。以下是标准判定流程:
- 幅度判定:当前值是否超过基线上下界的 N 倍标准差(通常取 2σ 或 3σ)。
- 持续时间判定:偏离状态是否持续超过 M 个连续采样周期(如 3 个 1 分钟窗口)。
- 趋势判定:偏离方向是持续恶化、稳定偏离还是快速回归。
只有同时满足幅度 + 持续时间两个条件,才判定为有效偏离,触发告警或自动化核验流程。趋势判定用于决定告警优先级:
| 趋势类型 | 判定条件 | 推荐动作 |
|---|---|---|
| 快速恶化 | 连续 3 个周期偏离幅度递增 > 50% | 立即告警 + 自动化回滚 |
| 稳定偏离 | 偏离幅度稳定在 2σ~3σ 之间 | 告警 + 值班确认 |
| 快速回归 | 偏离后 2 个周期内回到基线内 | 记录日志,不告警 |
常见陷阱:仅依赖幅度判定会导致“毛刺告警”(短暂抖动被误报);仅依赖持续时间会导致“慢速恶化漏报”(指标缓慢爬升但始终未超阈值)。必须两者结合,并引入趋势分析。
2.4 基线偏离判定流程图
下图展示了从指标采集到偏离判定的完整流程,包含幅度、持续时间、趋势三个判定阶段:
2.5 基线偏离的自动化核验触发条件
在 on-call 自动化集成中,基线偏离判定结果直接决定是否触发核验流程。以下是标准触发条件矩阵:
| 判定结果 | 触发动作 | 值班响应等级 |
|---|---|---|
| 有效偏离(快速恶化) | 立即触发自动化核验 + 告警 | P0(最高) |
| 有效偏离(稳定偏离) | 触发自动化核验 + 通知值班 | P1 |
| 有效偏离(快速回归) | 仅记录日志,不触发核验 | 无 |
| 无效偏离 | 不触发任何动作 | 无 |
自动化核验触发时机:有效偏离判定完成后,立即启动基线核验脚本。核验内容包括:检查指标数据源是否正常、对比同区域/同集群的指标是否一致、验证基线窗口是否被污染(如发布期间的数据不应参与基线计算)。核验结果将决定告警是否升级为故障单。
2.6 基线偏离判定示例(代码片段)
以下 Python 代码展示了基线偏离判定的核心逻辑,包含幅度、持续时间、趋势三个维度的计算:
import numpy as np
from collections import deque
class BaselineDeviationDetector:
def __init__(self, sigma_threshold=2.0, duration_threshold=3):
self.sigma_threshold = sigma_threshold
self.duration_threshold = duration_threshold
self.history = deque(maxlen=10) # 保存最近10个周期的偏离状态
def check_deviation(self, current_value, baseline_mean, baseline_std):
"""
返回: (is_deviation: bool, trend: str)
"""
# 1. 幅度判定
z_score = (current_value - baseline_mean) / (baseline_std + 1e-9)
amplitude_deviation = abs(z_score) >= self.sigma_threshold
# 2. 持续时间判定
self.history.append(amplitude_deviation)
duration_deviation = sum(self.history) >= self.duration_threshold
# 3. 趋势判定
if duration_deviation and amplitude_deviation:
# 检查最近3个周期是否持续恶化
recent = list(self.history)[-3:]
if all(recent) and z_score > 0:
trend = "rapid_worsening" if z_score > 3.0 else "stable_deviation"
else:
trend = "rapid_return"
else:
trend = "no_deviation"
is_deviation = amplitude_deviation and duration_deviation
return is_deviation, trend
代码说明:上述代码中,
sigma_threshold 控制幅度敏感度(默认 2σ),duration_threshold 控制持续时间窗口(默认 3 个周期)。趋势判定通过检查最近 3 个周期的偏离状态和 Z-Score 方向实现。实际生产环境中,建议将 history 替换为 Redis 或时间序列数据库,以支持分布式部署。
2.7 基线偏离的常见误判场景与规避
即使有完善的判定逻辑,基线偏离仍可能出现误判。以下是三种典型场景及规避策略:
| 误判场景 | 原因 | 规避策略 |
|---|---|---|
| 发布后误报 | 新版本指标与旧基线不匹配 | 发布后自动冻结基线 30 分钟,重新校准 |
| 流量突增误报 | 促销/活动导致正常流量峰值被判定为偏离 | 引入业务日历,活动期间使用独立基线 |
| 数据源抖动误报 | 监控系统自身故障导致指标异常 | 增加数据源健康检查,异常数据不参与判定 |