跳到主要内容

运维篇 · 02 · 监控与告警

本章目标

建立分层、可观测、不扰民的监控体系,让问题在用户发现前被发现。

一、三层监控模型

┌────────────────────────────────────┐
│ Layer 1: 业务层 │
│ "用户能不能下单?订单数有没有掉?" │
├────────────────────────────────────┤
│ Layer 2: 应用层 │
│ "接口响应时间、错误率、吞吐" │
├────────────────────────────────────┤
│ Layer 3: 基础层 │
│ "CPU、内存、磁盘、网络" │
└────────────────────────────────────┘

优先级:业务层 > 应用层 > 基础层。

二、业务层监控(最重要)

2.1 核心原则

监控业务结果,而不仅仅是技术指标。

❌ 只监控:"接口没报错" → 用户没下单你不知道 ✅ 监控:"订单数/分钟"、"支付成功率" → 真正看到业务健康度

2.2 推荐的业务指标

指标例子告警阈值
核心转化率下单成功率下降 > 5%
核心操作量订单/分钟环比下降 > 30%
关键流程耗时下单到支付平均时长上升 > 20%
业务异常支付失败数/分钟激增 > 2 倍
用户体验首屏加载时间 P95上升 > 30%

2.3 业务监控的实现

埋点 → 聚合 → 看板

应用代码 ─埋点─► 消息队列 ─聚合─► 时序数据库 ─查询─► 看板 + 告警

推荐工具组合:

  • 埋点:OpenTelemetry / 自研 SDK
  • 聚合:Flink / Kafka Streams
  • 存储:Prometheus / InfluxDB / VictoriaMetrics
  • 看板:Grafana
  • 告警:Alertmanager / 自研

三、应用层监控

3.1 RED 方法

对每个服务监控三个维度:

字母含义例子
Rate请求速率(QPS)1200 req/s
Errors错误率0.05%
Duration延迟分布(P50/P95/P99)P99 = 180ms

3.2 USE 方法(用于资源)

字母含义例子
Utilization使用率CPU 65%
Saturation饱和度队列堆积 500
Errors错误OOM kill 次数

3.3 应用层监控清单

必须监控

  • 每个接口的 QPS / 错误率 / 延迟
  • 数据库连接池状态
  • 外部依赖调用(成功率、延迟、超时)
  • 消息队列积压
  • 缓存命中率
  • 定时任务执行情况
  • GC 次数与时长(JVM / Node)

四、基础层监控

4.1 必须监控的基础指标

主机

  • CPU(整体 + 单核)
  • 内存(已用 / 可用 / swap)
  • 磁盘(空间 + IOPS + 延迟)
  • 网络(带宽 + 丢包 + 错误)
  • 负载(load average)

容器 / Pod

  • 资源使用率 vs request/limit
  • 重启次数
  • OOM 次数

网络

  • 入口 / 出口带宽
  • TCP 连接数
  • DNS 解析时长

4.2 推荐工具

平台推荐
物理机 / 虚拟机Prometheus + node_exporter
KubernetesPrometheus + kube-state-metrics
云原生厂商原生(CloudWatch / Azure Monitor / Stackdriver)

五、日志

5.1 日志分级

级别用途生产环境
TRACE最细节调试❌ 关闭
DEBUG调试❌ 关闭(除非紧急排查)
INFO关键业务事件✅ 开启
WARN异常但可恢复✅ 开启
ERROR异常错误✅ 开启 + 监控
FATAL不可恢复错误✅ 开启 + 告警

5.2 结构化日志

不推荐(字符串拼接):

log.info("User " + userId + " placed order " + orderId + " with amount " + amount)

推荐(结构化):

{
"timestamp": "2026-04-15T10:30:00.123Z",
"level": "INFO",
"service": "order-service",
"trace_id": "req-abc-123",
"user_id": "usr-42",
"event": "order_placed",
"order_id": "ord-88",
"amount": 299.99,
"currency": "CNY"
}

好处:可搜索、可聚合、可告警。

5.3 日志必带字段

字段说明
timestampISO 8601 格式,含时区或 UTC
level日志级别
service服务名
trace_id全链路追踪 ID
span_id跨服务追踪
user_id / tenant_id业务维度
event事件类型(便于聚合)

5.4 日志采集

应用 ─stdout/文件─► 采集 agent ─► 消息队列 ─► 存储 ─► 查询
(Filebeat/Fluentd) (Kafka) (ES/Loki) (Kibana/Grafana)

规则

  • 应用只管写日志,不直接发网络
  • 采集 agent 负责可靠传输
  • 采集失败要有本地 buffer

5.5 敏感信息过滤

绝对不能记录

  • 密码(哪怕 hash 过)
  • 完整信用卡号
  • 身份证号
  • 手机号 / 邮箱(可做脱敏:1****5678
  • Token / API Key
  • 完整请求 header(可能含 Authorization)

在代码或采集端过滤

六、全链路追踪

6.1 用途

  • 定位跨服务的慢点
  • 还原异常发生时的完整调用链
  • 分析接口依赖关系

6.2 OpenTelemetry 标准

[Client] → [Gateway] → [Service A] → [Service B] → [DB]
↓ ↓ ↓
Span 1 Span 2 Span 3

所有 Span 属于同一个 Trace(共享 trace_id)

6.3 接入要点

  • 所有服务使用统一的 tracing SDK
  • 在网关注入 trace_id,全程透传
  • 关键业务事件手动打 span(如"写数据库"、"调用第三方")
  • 采样策略:100% 采样慢请求和错误请求,1% 正常请求

七、告警

7.1 告警的 4 个原则

  1. 可行动:收到告警后知道要做什么
  2. 可定位:能快速找到问题根源
  3. 不误报:误报 > 10% 就会被忽略
  4. 不漏报:真问题必须告警

7.2 告警分级

级别响应时间通知方式示例
P0 紧急5 分钟电话 + 短信 + IM核心服务不可用
P1 严重15 分钟短信 + IM错误率飙升
P2 一般1 小时IM + 邮件单实例 CPU 高
P3 轻微下一工作日邮件磁盘使用率 70%

7.3 告警降噪

合并相似告警

  • 同一问题引发的多条告警,合并成一条
  • 短时间内重复告警,等待窗口内聚合

抑制依赖告警

  • 主服务挂了,不需要再报所有依赖它的服务

升级机制

  • P2 告警 1 小时无人处理 → 升级为 P1
  • 值班人不响应 15 分钟 → 通知 backup

7.4 告警阈值的三种方式

方式说明适合
静态阈值CPU > 80%资源类指标
同比/环比QPS 环比下降 30%业务类指标
动态基线偏离历史均值 3 sigma波动大的指标

7.5 告警示例(Prometheus)

groups:
- name: api-alerts
rules:
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m])) /
sum(rate(http_requests_total[5m])) > 0.01
for: 5m
labels:
severity: P1
annotations:
summary: "API 错误率超过 1%"
description: "当前错误率: {{ $value | humanizePercentage }}"
runbook: "https://wiki/runbook/high-error-rate"

八、看板(Dashboard)

8.1 看板分层

层级受众例子
概览板高管 / 一线值班一页全景(业务、应用、基础)
服务板服务 owner本服务详细指标
故障板故障时临时专项分析

8.2 好看板的标准

  • 一眼能看出"好 or 坏"(红/绿色块)
  • 关键指标在首屏
  • 有明显的时间范围选择
  • 支持下钻(点击图表进入详情)
  • 有文字注解(不仅是数字)

九、监控成熟度模型

等级特征改进方向
L1 被动用户反馈才知道出事加基础监控
L2 反应监控发现,人工介入加告警
L3 主动告警准确,有 runbook加自动化处置
L4 预防异常趋势即报警加预测告警
L5 自愈部分问题自动处置持续优化

十、配套资源