架构(07):可观测性设计——Metrics/Logs/Traces 三支柱、OpenTelemetry
更新时间:2026-09-02。本文是
architecture/架构领域第 07 篇,接 分布式一致性。可观测性解决"系统出了什么问题"和"为什么出问题"。Metrics 告诉你"系统慢了",Logs 告诉你"在哪慢了",Traces 告诉你"为什么慢"。三支柱缺一不可。
本文要回答的问题
- 可观测性(Observability)和监控(Monitoring)有什么区别?
- Metrics/Logs/Traces 三支柱各做什么?怎么配合?
- OpenTelemetry 是什么?为什么需要标准化?
- 采样策略怎么选?头采样 vs 尾采样?
- 告警怎么设计?告警风暴怎么避免?
一、可观测性 vs 监控
监控(Monitoring):
你提前知道要监控什么(CPU、内存、QPS)
基于已知的指标,告警已知的问题
可观测性(Observability):
你不知道会发生什么问题
问题发生了,你可以通过数据排查,找到原因
区别:
监控:知道要监控什么,提前配好
可观测性:不知道要查什么,但能查
结论:可观测性包含监控,监控是基础,可观测性是高级能力二、三支柱
1. Metrics(指标)
指标:系统运行状态的数值,聚合数据
类型:
Counter(计数器):只增不减(QPS、请求总数)
Gauge(仪表盘):可增可减(内存使用率、连接数)
Histogram(直方图):分布统计(请求延迟 P50/P99/P999)
Summary(汇总):滑动窗口统计(同 Histogram,但在客户端计算)
典型工具:
Prometheus + Grafana
Datadog
VictoriaMetrics
适用场景:
- 告警:QPS 异常、内存使用率过高
- 容量规划:QPS 趋势、资源使用趋势
- 性能分析:P99 延迟趋势维度:
指标 + 标签(Label) → 多维数据
示例:
http_request_total{method="GET", status="200", path="/api/order"}
http_request_total{method="POST", status="500", path="/api/payment"}
通过标签,可以按维度聚合:
总 QPS:sum(http_request_total)
按状态分组:sum by(status) (http_request_total)
按路径分组:sum by(path) (http_request_total)2. Logs(日志)
日志:系统运行的事件记录,文本
类型:
结构化日志(JSON):便于查询,推荐
非结构化日志(文本):难查,不推荐
典型工具:
ELK(Elasticsearch + Logstash + Kibana)
Loki(Grafana 的日志系统,轻量)
Datadog Logs
适用场景:
- 错误排查:看详细错误信息
- 审计:访问记录
- 分析:用户行为分析日志规范:
推荐结构化日志(JSON):
{"time":"2026-09-02T10:00:00Z","level":"error","service":"order-service",
"trace_id":"abc123","message":"数据库连接超时","error":"connection timeout","duration_ms":5000}
规范:
1. 统一格式(JSON 或结构化文本)
2. 包含 trace_id(关联链路追踪)
3. 包含 service_name
4. 包含 level(error/warn/info/debug)
5. 不要打印敏感信息3. Traces(链路追踪)
链路追踪:一次请求经过的所有服务,串起来
Trace → Span → Span → Span
一个 Trace 包含多个 Span:
Span1:API 网关 → 用户服务
Span2:用户服务 → 订单服务
Span3:订单服务 → 数据库
每个 Span 包含:
trace_id(一次请求的 ID)
span_id(当前操作的 ID)
parent_span_id(父操作的 ID)
start_time + duration
service_name + operation_name
典型工具:
Jaeger
Zipkin
SkyWalking
Datadog APM
适用场景:
- 排查慢请求:看哪个 Span 最慢
- 服务依赖分析:看服务之间的调用关系
- 错误定位:看哪个 Span 出错了三、OpenTelemetry
OpenTelemetry 是可观测性数据的标准,统一 SDK
以前:每个工具自己写 SDK
Prometheus SDK(指标)
ELK SDK(日志)
Jaeger SDK(链路追踪)
现在:OpenTelemetry 统一
一个 SDK,同时输出指标、日志、链路追踪
数据格式标准化,各种后端都可以接
OpenTelemetry 架构:
SDK(应用内) → Collector(收集器) → Backend(存储/展示)
↓ ↓
Prometheus Jaeger
Loki Datadog
优点:
标准化:切换工具,不需要改代码
统一:指标、日志、链路追踪用同一个 SDK
生态:主流云厂商都支持
Vendor-neutral:不绑定任何厂商四、采样策略
链路追踪如果全量采样,数据量太大,存储贵
所以 99% 场景用采样,只保存部分数据
采样策略:| 策略 | 原理 | 适合场景 |
|---|---|---|
| 固定采样率 | 随机采样,比如 1% | 流量大,需要控制成本 |
| 动态采样(头采样) | 根据请求特征决定是否采样(如 /api/payment 100% 采样) | 需要保留关键请求 |
| 尾采样 | 先全量处理,再决定哪些保留(如慢请求保留) | 需要保留异常请求 |
| 自适应采样 | 根据流量变化自动调整采样率 | 流量波动大 |
推荐: 头采样 + 尾采样组合
- 关键接口(支付、下单)100% 采样
- 一般接口固定采样率 1%
- 慢请求(> 1s)强制采样
五、告警设计
告警原则
1. 只告警需要人工处理的问题
不要告警常识(服务器重启了,小问题)
告警太多,人就不看了(告警疲劳)
2. 告警要有行动指引
告警说:内存使用率 > 90%,扩容
不要只说:内存使用率高
3. 避免告警风暴
一个根因导致 N 个告警
只告警一个,不说 N 个告警级别
| 级别 | 颜色 | 响应时间 | 示例 |
|---|---|---|---|
| Critical | 红色 | 立即处理 | 服务不可用、数据丢失 |
| Warning | 橙色 | 工作时间 | 内存超 80%、P99 延迟超 1s |
| Info | 蓝色 | 记录 | 部署完成、配置变更 |
告警规则示例
# 5xx 错误率 > 1%
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.01
# P99 延迟 > 1s
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1
# 内存使用率 > 90%
node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes > 0.9六、常见坑对照
| 错误 | 后果 | 对策 |
|---|---|---|
| 只有指标,没有链路追踪 | 知道慢了,不知道哪慢 | 三支柱缺一不可 |
| 日志没结构化 | 难查,难分析 | 用 JSON 结构化日志 |
| 没有 trace_id | 日志和链路追踪对不上 | 日志加 trace_id |
| 全量采样 | 存储成本高,查询慢 | 采样,关键接口 100% |
| 告警太多 | 告警疲劳,没人看 | 只告警需人工处理的 |
| 没有告警 | 出问题没人知道 | 至少配 Critical 告警 |
相关与延伸
下一篇:高并发架构——缓存分层、削峰填谷、异步化、无状态化;分布式一致性,见 分布式一致性——CAP、BASE、Raft。
一句话总结
可观测性:三支柱——Metrics(指标,Prometheus + Grafana 聚合数据,用于告警/容量规划)、Logs(日志,ELK/Loki 结构化 JSON 事件记录,用于排查问题)、Traces(链路追踪,Jaeger 串起一次请求经过的所有服务,用于定位慢/错误);OpenTelemetry 统一 SDK,一个 SDK 同时输出三支柱,切换工具不需要改代码;采样策略:关键接口 100% 采样,一般接口固定 1%,慢请求强制采样;告警:只告警需人工处理的问题,有行动指引,避免告警风暴;原则:三支柱缺一不可,日志必须有 trace_id 关联链路追踪。