Skip to content
bitzorcas
中EN

Guide

监控、告警与 Runbook

从 OpenTelemetry 信号、SLI/SLO 和依赖积压建立可行动告警,并为每条告警绑定恢复手册。

Last updated

监控回答“系统现在怎样”,告警回答“是否需要人介入”,Runbook 回答“接到告警后先做什么”。三者必须从同一服务目标和故障模型推导,不能只因为某个指标容易采集就设置阈值。

信号到行动

API / JobHost / Dependencies

Logs + Metrics + Traces

OTel Collector / Backend

Dashboard

SLO-based alert

Runbook + owner

Mitigate / rollback / recover

Post-incident learning

最小 SLI 集合

范围指标为什么重要
HTTP请求率、错误率、延迟分位数、并发直接反映用户体验
数据库连接池、超时、死锁/并发冲突、慢查询发现共享瓶颈与容量风险
CAP/RabbitMQ待发布、待消费、重试、最老消息年龄发现最终一致性停滞
JobHost调度延迟、成功/失败、重试、租约状态发现后台闭环断裂
Redis可达性、延迟、内存、逐出、锁降级缓存、幂等与协调共同依赖
审计队列深度、丢弃/失败、写入延迟合规证据不能静默消失
Adapter当前实现类型与 Readiness防止生产解析到默认/Unavailable

阈值从测得的基线、容量和 SLO 推导。本手册不硬编码某个环境的百分位或队列数量;生产值进入监控配置,并在容量或版本变化后重新校准。

Kubernetes 探针示例

# ① Liveness 只判断进程是否需要重启,不能依赖短暂不可用的外部系统。
livenessProbe:
httpGet: { path: /health/live, port: 8080 }
periodSeconds: 10
# ② Readiness 决定是否接流量,可包含当前请求必需的窄依赖探针。
readinessProbe:
httpGet: { path: /health/ready, port: 8080 }
periodSeconds: 5
failureThreshold: 3

告警设计

  • 优先告警用户影响、错误预算消耗和持续积压,不告警每一次瞬时异常;
  • Warning 给调查窗口,Critical 代表正在影响交付或数据安全;
  • 每条告警包含服务、环境、租户范围(可安全提供时)、开始时间、Dashboard 和 Runbook;
  • 使用脱敏关联 ID 连接日志与 Trace,不把 Secret 或个人信息放进 Label;
  • 对“告警本身失效”设置 Dead Man/遥测缺失检测。

Runbook 模板

  1. 确认影响:哪些端点、租户、消息或作业受到影响?
  2. 判定依赖:Readiness、数据库、RabbitMQ、Redis、外部 Adapter 谁先异常?
  3. 控制风险:摘流量、暂停消费者、失败关闭高价值写入或回滚版本。
  4. 恢复事实:恢复依赖后核对 Outbox、幂等记录、任务状态和审计,没有重复或缺失。
  5. 验证服务:运行窄 Smoke、观察错误预算和积压下降,再完全恢复流量。
  6. 留下证据:时间线、根因、客户影响、临时措施、长期行动和 Owner。

告警演练至少覆盖数据库不可达、RabbitMQ 积压、Redis 锁 Deny、JobHost 停止、审计写入失败和错误 Adapter。详细信号语义见可观测性,灾难级恢复见灾难恢复。

当前 OTel 与健康语义

ServiceDefaults 统一注册 ASP.NET Core、HttpClient、Runtime 指标,框架 ActivitySource,以及 JobHost Quartz 和数据库慢查询 Meter。Trace、Metric、Log 都通过 OTEL_EXPORTER_OTLP_ENDPOINT 输出。

/health/live 只筛选 live tag 的 self check;/health/ready 只汇总 ready 依赖。兼容端点 /health 会运行全部检查,不能把它误用为轻量 liveness。

Terminal window
# ① 分开探测进程存活和依赖就绪,并保留 HTTP 状态与耗时。
curl -fsS -o /dev/null -w 'live %{http_code} %{time_total}\n' "$URL/health/live"
curl -fsS -o /dev/null -w 'ready %{http_code} %{time_total}\n' "$URL/health/ready"
# ② 用标准环境变量控制采样;先在 Staging 验证后再降低生产比例。
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.10

告警与发布关联

Dashboard 至少按 service.name、service.version 与 deployment.environment 切分。发布标记应关联镜像摘要和 Commit,才能判断错误率变化来自新版本、依赖故障还是流量结构。

高基数 tenantId、userId、URL 原始 ID 不应成为 Metric label;需要租户调查时使用受控日志或 Trace 查询。

Runbook 验证

每条 Critical 告警至少季度演练一次:触发可控故障,确认通知路由、值班响应、止损权限、恢复命令和证据归档。只阅读 Runbook 不能证明它可执行。

Alert → owner acknowledged → impact scoped → traffic/consumer contained
→ dependency recovered → outbox/task/audit reconciled
→ narrow smoke → backlog drains → close with timeline

完成清单

  • live 与 ready 的依赖集合符合重启/摘流量语义;
  • OTel Collector 不可用不会静默耗尽应用内存或磁盘;
  • 告警覆盖用户影响、错误预算和持续积压;
  • 每条告警有 owner、Dashboard、Runbook 与升级路径;
  • 发布、事故、回滚和恢复能够用 correlation/trace 串联;
  • 遥测缺失本身有 Dead Man 告警。

首个 Dashboard

按 API、JobHost、数据库、消息与 Redis 分五行展示:流量/吞吐、错误、延迟、饱和度和最近发布标记。每个面板链接对应日志或 Trace 查询,并明确时区与采样率。

Dashboard 不展示无 Owner 的“漂亮指标”。每个图要么支持 SLO、容量、发布判断或 Runbook,要么删除。

部署后至少观察一个完整业务高峰,并比较发布前基线。低流量环境使用合成 smoke 和作业心跳,避免“没有数据”被当成健康。

对 CAP、审计和 JobHost 使用最老积压年龄,而不只看数量;数量不变但年龄持续上升通常更能说明闭环停止。

  • 视图默认展示当前环境,同时允许对照上一版本;
  • 关键查询保存为代码并经过评审;
  • Dashboard 变更跟随发布版本;
  • 长期趋势用于容量,短窗口用于事故;
  • 权限确保租户与个人数据不会越权暴露。

100%

滚轮或按钮缩放 · 放大后拖动画面 · 双击切换 100% / 200%