分布式可观测性
可观测性(Observability)是通过系统的外部输出理解其内部状态的能力。它不仅回答“系统是否异常”,还要支持继续追问“为什么异常”,尤其要能帮助排查事先没有为它单独配置告警的新问题。
可观测性、监控与遥测
这三个概念经常混用,但关注点不同:
| 概念 | 含义 | 典型问题 |
|---|---|---|
| 遥测(Telemetry) | 系统产生并传出的运行数据 | 采集了哪些指标、日志和 Span? |
| 监控(Monitoring) | 对已知状态进行测量、展示和告警 | 错误率是否超过阈值? |
| 可观测性(Observability) | 利用遥测数据理解系统行为的能力 | 为什么只有某个区域的新版本请求变慢? |
采集了大量数据,不代表系统已经具备可观测性。如果字段不一致、上下文无法关联、关键路径没有埋点,故障发生后依然无法回答问题。
常见遥测信号
“指标、日志、链路追踪是可观测性三支柱”是有用的入门模型,但它不是严格边界。现代系统还会使用事件、持续性能剖析等信号。
| 信号 | 擅长回答 | 数据特点 | 常见风险 |
|---|---|---|---|
| 指标(Metrics) | 是否异常、影响有多大 | 聚合时间序列,查询快 | 高基数标签导致成本失控 |
| 日志(Logs) | 具体发生了什么 | 离散事件,细节丰富 | 噪声、敏感数据、存储量大 |
| 链路(Traces) | 一次请求如何跨服务执行 | 请求级上下文和因果路径 | 采样不当、上下文断裂 |
| 事件(Events) | 系统何时发生配置或状态变化 | 稀疏、语义明确 | 变更来源记录不完整 |
| 性能剖析(Profiles) | CPU 或内存消耗在哪段代码 | 代码级聚合样本 | 额外开销与符号管理 |
三种核心信号的典型协作方式是:
指标发现影响范围 → 链路定位慢服务或错误路径 → 日志解释具体业务状态和异常细节。
从埋点到分析的完整管道
OpenTelemetry 覆盖遥测数据的生成、上下文传播、接收、处理和导出,但它本身不是存储与查询后端。引入 Collector 的主要价值是把重试、批处理、路由、采样和敏感字段过滤从业务进程中解耦出来。
从用户体验选择指标
四个黄金信号
Google SRE 总结的四个黄金信号适合面向请求的在线服务:
- 延迟(Latency):成功请求和失败请求的耗时应分开观察。
- 流量(Traffic):QPS、并发连接、消息消费速率等系统需求量。
- 错误(Errors):显式失败、错误结果和违反 SLO 的慢请求。
- 饱和度(Saturation):系统最受限资源的使用程度和排队情况。
RED 与 USE
- RED 适合服务端请求:Rate(速率)、Errors(错误)、Duration(耗时)。
- USE 适合资源:Utilization(利用率)、Saturation(饱和度)、Errors(错误)。
不要为了完整而给每个组件堆满指标。先从用户可感知的 SLI 开始,再补充能够解释它的服务和资源指标。
高基数为什么危险
指标后端会为每种标签组合维护独立时间序列。service、region、status_code 通常有界;user_id、order_id、完整 URL 和 trace_id 可能几乎每次请求都不同,不适合作为普通指标标签。
需要从聚合指标跳到单次请求时,可以使用带 trace_id 的 exemplar,或者从日志、链路系统中检索,而不是把请求 ID 直接放进指标标签。
一次跨信号排障示例
假设“创建订单”的 P99 延迟突然从 300 ms 升到 2 s:
- 指标确认异常只发生在
region=cn-east、version=2.3.1,错误率没有明显上升。 - 从延迟直方图的 exemplar 跳转到一条慢 Trace。
- 链路显示库存服务本身只执行了 80 ms,但调用前出现 1.4 s 的排队空白。
- 日志通过相同
trace_id找到连接池获取超时,并确认没有记录密码或数据库连接串。 - 部署事件显示该区域刚把连接池上限从 100 调成 20。
- 修复配置后,用同一组 SLI 验证 P99 和饱和度恢复。
图示参考:OpenTelemetry Observability Primer 与 Google SRE:Monitoring Distributed Systems
这个过程依赖共同的资源属性,如 service.name、service.version、deployment.environment.name 和 cloud.region。如果各团队使用不同字段名,即使数据都已采集,也难以可靠关联。
埋点与数据建模原则
统一资源与属性
优先采用 OpenTelemetry Semantic Conventions 等公共约定,并为内部业务字段制定稳定规范。属性应描述实际语义,而不是绑定某个后端的查询写法。
自动埋点与手动埋点结合
自动埋点适合 HTTP、RPC、数据库和常见框架调用;手动埋点用于“创建订单”“库存预占”等业务边界。只有技术 Span 而没有业务语义,往往只能看到调用慢,却无法判断业务是否正确。
控制成本,而不是盲目少采
- 指标:限制标签基数,优先使用直方图观察延迟分布。
- 链路:用头部采样控制基础流量,用尾部采样保留错误和高延迟请求。
- 日志:按查询价值决定级别、字段和保留周期,不把 DEBUG 永久留在生产环境。
- 全部信号:尽早过滤密钥、Token 和个人敏感信息。
监控遥测管道自身
采集器丢数据时,业务看板可能看似“恢复正常”。因此还要监控 Collector 的接收拒绝量、导出失败量、队列使用量、处理延迟和资源占用。
最小落地路线
- 为一条关键用户旅程定义 SLI、SLO 和错误预算。
- 统一服务名、环境、版本、区域等资源属性。
- 接入 HTTP/RPC 自动埋点,并补充少量业务 Span。
- 输出结构化日志,自动注入
trace_id和span_id。 - 通过 Collector 集中完成批处理、重试、过滤和导出。
- 建立 RED 看板,并只对用户影响和 SLO 消耗告警。
- 演练一次真实故障,验证能否从指标跳到 Trace,再关联到日志和变更事件。
学习自测
- 为什么“部署了 Prometheus、Loki 和 Jaeger”不等于具备可观测性?
user_id为什么通常不适合作为指标标签,却可以作为受控的日志字段?- 自动埋点已经覆盖 HTTP 调用时,为什么还需要业务 Span?
- 遥测 Collector 停止导出时,应该由哪些独立信号发现?
延伸阅读
- OpenTelemetry:Observability Primer
- OpenTelemetry:What is OpenTelemetry?
- OpenTelemetry:Collector
- OpenTelemetry:Semantic Conventions
- Google SRE Book:Monitoring Distributed Systems