Skip to content

Observability(可观测性)—— 让系统内部状态可见 ​

解决什么问题:生产环境出问题时"看不到、查不到、不知道为什么"—— 可观测性 = 系统在被询问时能告诉你它内部发生了什么—— 通过 Logs(事件流)/ Metrics(数值)/ Traces(请求链)让内部状态可见。 没有可观测性 = 反馈环测量环节缺失 = 控制论意义上的失控。

它是什么 ​

Observability(可观测性) 是 L2 设计层的核心质量属性——指系统能通过外部输出推断内部状态的能力。

可观测性的 3 大支柱:

支柱数据形态用途
Logs(日志)离散事件"发生了什么"
Metrics(指标)数值时间序列"现在状态如何"
Traces(追踪)请求链路"调用链如何流转"

SE@G Ch 23(Winters / SRE)原话: "Observability is the ability to ask questions about your system without shipping new code. Logs, metrics, and traces are the three pillars that make this possible."

控制论 Ch 4 §4.6(钱学森): "反馈控制系统... 只有能测量的输出,才能形成有效的反馈。"

可观测性 = 控制论"反馈环"的"测量"环节的工程化。

可观测性 vs 监控:

维度可观测性监控
范围全量内部状态可见预定义指标的告警
问题"为什么""出事了"
数据高维、关联、可查询单维、聚合、阈值告警
应对未知问题的根因分析已知问题的快速响应

V2 视角(V2.7 B5 段 3 反馈 + B2 段 4 Hyrum's Law): 可观测性 = 反馈环的"测量"环节——没有可观测性的系统 = 反馈环不闭合 = 失控。 可观测性也对抗 Hyrum's Law——契约未被使用 = 契约未被测量 = 隐性技术债。

关键属性 ​

属性值/含义
高基数可按任意维度查询(用户 ID / 请求 ID / 标签)
关联性跨服务/跨事件的关联 ID
时序性严格时间戳 + 因果顺序
可查询支持任意维度的实时查询
低成本不影响生产性能(采样 / 聚合)
可保留数据可长期存储(小时 → 天 → 月)
告警友好支持阈值告警 + 异常检测
反模式只采不查 / 无 traceId / 日志不可解析 / 无关联
判错标志出问题只能看日志末尾 / 跨服务问题查不到原因 / 监控告警风暴

怎么用 ​

场景 1:结构化日志(Structured Logs) ​

python
import structlog

logger = structlog.get_logger()

# ❌ 非结构化日志(难以查询)
logger.info(f"Order {order_id} created by customer {customer_id} with {len(items)} items")

# ✅ 结构化日志(可查询)
logger.info("order.created",
    order_id=order.id,
    customer_id=order.customer_id,
    item_count=len(order.items),
    total_amount=str(order.total_amount),
    trace_id=current_trace_id,
)

结构化日志的 5 个核心规则:

  1. JSON 格式——机器可解析
  2. 关键字段——业务 ID(orderId / customerId)+ traceId
  3. 时间戳——ISO 8601 + 毫秒精度
  4. 日志级别——DEBUG / INFO / WARN / ERROR / FATAL
  5. 不要敏感信息——密码 / 身份证 / 银行卡绝不写入日志

场景 2:Metrics(指标)—— 数值时间序列 ​

python
from prometheus_client import Counter, Histogram, Gauge

# Counter(累计计数)
orders_created = Counter(
    "orders_created_total",
    "Total number of orders created",
    ["customer_segment", "order_type"]  # 标签维度
)

# Histogram(分布统计)
order_amount = Histogram(
    "order_amount_cny",
    "Order amount distribution",
    buckets=[10, 50, 100, 500, 1000, 5000, 10000]
)

# Gauge(当前状态)
active_orders = Gauge(
    "active_orders_count",
    "Currently active orders in the system"
)

# 使用
orders_created.labels(customer_segment="vip", order_type="online").inc()
order_amount.observe(order.total_amount.value)
active_orders.inc()

Metrics 的 4 类指标(USE / RED 框架):

框架维度指标
USE资源(每台机器)Utilization / Saturation / Errors
RED服务(每个端点)Rate / Errors / Duration
4 大黄金信号整体Latency / Traffic / Errors / Saturation
业务指标业务层面订单量 / GMV / 转化率

场景 3:Distributed Tracing(分布式追踪) ​

python
from opentelemetry import trace

tracer = trace.get_tracer("order-service")

# 创建 span
with tracer.start_as_current_span("place_order") as span:
    span.set_attribute("customer.id", customer_id)
    span.set_attribute("order.items_count", len(items))
    
    # 跨服务调用会自动传播 trace context
    with tracer.start_as_current_span("inventory.reserve") as child_span:
        result = inventory_client.reserve(items)
        child_span.set_attribute("inventory.reserved_count", result.count)
    
    with tracer.start_as_current_span("payment.charge") as child_span:
        payment = payment_client.charge(amount)
        child_span.set_attribute("payment.amount", str(amount))

Trace 的 5 个核心概念:

  • Trace = 一次完整请求的调用链
  • Span = 调用链中的一个环节
  • TraceId = 整个调用链的唯一 ID(贯穿所有服务)
  • SpanId = 当前 span 的 ID
  • ParentSpanId = 上游 span 的 ID

Trace 的关键作用:

  • 看到完整调用链(不只是单服务)
  • 看到每个环节的耗时(定位慢在哪)
  • 看到每个环节的错误(定位失败在哪)

场景 4:关联 ID(Correlation ID)—— 跨服务追踪 ​

python
import uuid

class RequestContext:
    """请求上下文 = 跨服务/跨事件的关联 ID"""
    trace_id: str
    span_id: str
    user_id: str
    request_id: str

# HTTP 头传递
# X-Trace-Id: abc-123-xyz
# X-Request-Id: req-456

# 事件传递
@dataclass(frozen=True)
class OrderCreated:
    order_id: str
    customer_id: str
    trace_id: str        # 跨事件传递
    causation_id: str    # 直接父事件 ID

关联 ID 的 4 个核心作用:

  1. 跨服务串联——一个请求的完整链路
  2. 跨事件串联——异步系统的事件链
  3. 用户行为串联——一个用户的所有操作
  4. 故障定位——出问题能快速找到"所有相关日志"

场景 5:告警分级与降噪 ​

yaml
# SLO-based alerting(基于 SLO 的告警)
- alert: OrderErrorBudgetBurn
  expr: |
    sum(rate(orders_failed_total[5m])) /
    sum(rate(orders_total[5m])) > 0.01
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "订单错误预算燃烧率 > 1%"
    description: "过去 5 分钟订单错误率 > 1%,请检查"

# 多窗口告警(避免噪声)
- alert: HighLatencyMultiWindow
  expr: |
    (
      rate(http_request_duration_seconds_sum[1m]) /
      rate(http_request_duration_seconds_count[1m]) > 0.5
    )
    and
    (
      rate(http_request_duration_seconds_sum[1h]) /
      rate(http_request_duration_seconds_count[1h]) > 0.3
    )

告警分级的 4 个级别:

级别含义响应时间示例
P0 / Critical业务中断立即订单全挂
P1 / High部分功能受损15 分钟支付失败率 > 5%
P2 / Medium性能下降1 小时P99 延迟 > SLO
P3 / Low提示4 小时错误预算消耗快

场景 6:可观测性的"3 个反模式" ​

反模式 1:只采不查

yaml
症状:
  - 100+ 业务指标
  - 但没有人主动查询
  - 出了问题只能看 ERROR 日志

正解:
  - 每个指标必须服务一个"会被问到的问题"
  - 季度清理不用的指标
  - 指标要有 owner

反模式 2:无关联 ID

yaml
症状:
  - 订单服务有 traceId
  - 库存服务有自己的 requestId
  - 两个 ID 没关系

正解:
  - 同一请求的所有服务必须用同一 traceId
  - 异步事件必须带 traceId
  - 跨系统传递用 HTTP 头 / 事件字段

反模式 3:日志洪水

yaml
症状:
  - 每个请求 100+ 条日志
  - 存储成本失控
  - 真正的问题日志被淹没

正解:
  - 关键路径日志(INFO)
  - 调试日志用 DEBUG(按需开启)
  - 业务事件日志 = 状态变更(如 order.created)
  - 不要日志"普通操作"(如"读取成功")

常见误区 ​

  1. "可观测性 = 多采日志"——错。可观测性 = 能从外部推断内部状态,不是日志量
  2. "日志 = 可观测性"——错。日志只是 3 大支柱之一,Metrics + Traces 同样重要
  3. "告警 = 可观测性"——错。告警是"已知问题响应",可观测性是"未知问题定位"
  4. "高基数标签"——错。Metrics 标签基数高(用户 ID)= 存储爆炸。用 Traces 而非 Metrics
  5. "采样 = 丢数据"——半对。采样是有损压缩,关键路径 100% / 其他采样,不是简单丢弃
  6. "只关注技术指标"——错。业务指标 + 技术指标同样重要(订单成功率 vs CPU 利用率)
  7. "上线后再加可观测性"——错。可观测性是设计阶段就要规划——后期补 = 改不动 / 补不全

关键洞察 ​

可观测性 = 控制论"反馈环"的"测量"环节的工程化—— 没有可观测性 = 反馈环不闭合 = 失控。

可观测性不是"加日志/加监控",是让系统能回答你"为什么"—— 当一个未知问题发生时,能不能在 30 分钟内找到根因,决定了系统能不能活。

V2 B5 反馈的工程含义—— Logs = 事件流(发生了什么) Metrics = 数值时间序列(现在状态) Traces = 调用链(哪里慢/哪里错) 三者互补,不可替代。

V2 B2 段 4 Hyrum's Law 的工程含义—— 没被测量的行为 = 隐性技术债。 没被观察的接口 = 隐性依赖。 可观测性 = 让"隐性"变"显性" = 让技术债可偿还。

判断可观测性是否足够的 5 个标准:

  1. 未知问题能在 30 分钟内定位(根因分析能力)
  2. 已知问题能在 5 分钟内告警(响应能力)
  3. 数据能跨服务/跨事件关联(全链路能力)
  4. 业务指标 + 技术指标都有(双视角能力)
  5. 告警噪声 < 5%(信噪比)

可观测性的最高境界 = "未知的未知"也能被回答—— 不是"出事了去找日志",是"系统出问题时能自动告诉你为什么"。

相关链接 ​

从名家方法论与工程化思路中蒸馏出自己的工程体系。