您的仪表板并没有告诉您您所认为的信息
大多数工程组织中都存在一个危险的假设:如果仪表板显示绿色,那么一切正常。这个假设导致的故障、静默数据损坏和周末紧急呼叫,比我能想到的任何单一技术故障都要多。问题不在于监控本身不好——而在于监控和可观测性解决的是根本不同的问题,大多数团队都在为实际工作使用错误的工具。
监控告诉您何时出现了故障。可观测性告诉您为什么。这种区别听起来很学术,直到您在处理一个故障已经三小时了,盯着一条平直的CPU图表和一个看起来很健康的错误率,而您的用户却在推特上发布您无法重现的500错误截图。
三大支柱已不再足够
可观测性社区喜欢谈论”三大支柱”——日志、指标和追踪。这种框架在2018年很有用,当时的主要目标是说服团队超越Nagios检查和日志文件。但在2026年,三大支柱的框架正在积极地误导人,因为它暗示拥有这三者就能自动获得可观测性。事实并非如此。
您可能有PB级的日志、数千个指标和完全仪器化的追踪,但仍然无法回答关于您系统的基本问题。可观测性不在于拥有数据——而在于无需部署新代码就能向您的系统提出任意问题。
这里有一个测试标准:您当前的设置能否回答一个您从未问过的问题?如果答案是否定的,那么您拥有的只是监控,而不是可观测性。
监控失效之处:真实案例
让我来介绍我在生产环境中见过的三个场景,在这些场景中,监控仪表板显示绿色,而系统实际上已经着火。
场景1:P99陷阱
一个支付处理服务报告了健康的 P50(12毫秒)和 P99(180毫秒)延迟。一切看起来都正常。但有一小部分用户——约0.3%——在每个请求上都遇到了30多秒的超时。P99指标完全掩盖了这个问题,因为分布有一个细长的尾部,只影响到访问特定数据库分区的用户。
# 仪表盘显示的内容:
# p50: 12ms ✅
# p99: 180ms ✅
# error_rate: 0.1% ✅
# 实际发生的情况:
# 延迟分布(简化):
# 0-50ms: 85%的请求
# 50-200ms: 14.7%的请求
# 200ms-1s: 0.2%的请求
# 1s-30s: 0.1%的请求 ← 这些用户非常愤怒
# 解决方案:基于user_id的高基数仪器化
# 可以进行即时查询
import opentelemetry.trace as trace
tracer = trace.get_tracer("payment-service")
@tracer.start_as_current_span("process_payment")
def process_payment(user_id, amount):
span = trace.get_current_span()
span.set_attribute("user.id", user_id)
span.set_attribute("payment.amount", amount)
span.set_attribute("db.partition", get_partition(user_id))
# 现在你可以查询:"显示所有db.partition=7且duration>5s的span"
场景2:静默数据损坏
一个ETL管道正在处理来自Kafka的事件并写入PostgreSQL。所有指标都很健康:吞吐量稳定,错误率为零,延迟最小。但管道有一个bug,它会静默丢弃包含基本多文种平面外Unicode字符的事件。没有抛出错误——事件只是在转换步骤中被过滤掉了。
监控无法捕捉到这一点,因为从系统角度看没有任何”错误”。管道完全按照代码指示的在工作。发现这个问题需要能够深入检查单个事件并比较输入与输出,这是一个可观测性问题。
场景3:级联重试风暴
服务A调用服务B,服务B调用服务C。服务C经历了短暂的延迟激增(从200毫秒到2秒)。服务B的重试逻辑启动,使服务C的负载增加了三倍。服务A的重试逻辑随后也启动了。在60秒内,服务C接收到的流量达到了正常水平的27倍。
每个服务的监控仪表盘单独看起来都很正常。服务C显示了延迟升高和请求量增加。但要理解因果关系链——即重试使情况变得更糟——需要分布式追踪,能够跟踪单个请求跨越所有三个服务。
真正的可观测性是什么样子
真正的可观测性有几个特点,使其与传统监控区分开来:
| 特性 | 监控 | 可观测性 |
|---|---|---|
| 问题类型 | 预定义(仪表板) | 临时性(探索性) |
| 数据模型 | 聚合指标 | 高基数事件 |
| 故障模式 | 已知未知 | 未知未知 |
| 成本驱动因素 | 指标数量 | 事件量和基数 |
| 主要工具 | 仪表板、警报 | 查询接口、跟踪浏览器 |
| 使用者 | 值班工程师 | 任何调试人员 |
高基数数据是关键
监控和可观测性之间的根本区别在于基数。监控系统将数据聚合为低基数维度:状态码、端点、区域。可观测性系统保留高基数维度:用户ID、请求ID、跟踪ID、会话ID。
# 低基数指标(监控):
http_requests_total{method="GET", status="200", endpoint="/api/users"} 145832
# 高基数事件(可观测性):
{
"timestamp": "2026-03-15T14:32:01.445Z",
"service": "api-gateway",
"trace_id": "abc123def456",
"span_id": "span_789",
"user_id": "user_42981",
"endpoint": "/api/users/42981/orders",
"method": "GET",
"status_code": 200,
"duration_ms": 847,
"db_query_count": 3,
"db_duration_ms": 612,
"cache_hit": false,
"response_size_bytes": 14520,
"feature_flags": ["new-order-index", "cache-v2"]
}
通过高基数事件,你可以回答从未预料到的问题:”哪些用户的cache_hit=false且duration_ms > 500并且正在使用new-order-index功能标志?”试着用Grafana仪表板回答这个问题。
2026年的工具生态
可观测性工具市场已经显著成熟,但也比以往任何时候都更加令人困惑。以下是对主要参与者的诚实评估:
OpenTelemetry:获胜的标准
OpenTelemetry 已经赢得了可观测性标准之战。如果你要启动新项目,请使用 OTel 进行可观测性配置,无需回头。收集器架构为你提供了供应商灵活性:
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1000
# 尾部采样:仅保留包含错误或高延迟的追踪
tail_sampling:
decision_wait: 10s
policies:
- name: errors
type: status_code
status_code: {status_codes: [ERROR]}
- name: slow-requests
type: latency
latency: {threshold_ms: 1000}
- name: baseline
type: probabilistic
probabilistic: {sampling_percentage: 10}
exporters:
otlp/honeycomb:
endpoint: "api.honeycomb.io:443"
headers:
"x-honeycomb-team": "${HONEYCOMB_API_KEY}"
prometheus:
endpoint: "0.0.0.0:8889"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, tail_sampling]
exporters: [otlp/honeycomb]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]
Honeycomb vs Datadog vs Grafana Cloud
Honeycomb 仍然是真正可观测性的黄金标准 — 他们的查询引擎处理高基数数据的能力无人能及。但对于高流量服务,他们的定价可能相当高昂。Datadog 提供一切服务,但对每项服务都单独收费,账单可能令人震惊。Grafana Cloud(配合 Tempo 和 Loki)提供了最佳的自托管替代方案,但需要更多的运营投入。
对于小型团队,我的真诚建议:从 Grafana Cloud 的免费层级开始用于指标和基础仪表板,添加 Honeycomb 的免费层级用于追踪和高基数查询,并使用结构化日志输出到标准输出,以便在需要时进行搜索。
从监控转向可观测性的实际步骤
步骤 1:使用 OpenTelemetry 进行可观测性配置
为你的服务添加 OTel 自动可观测性配置。对于大多数语言,这只需几行代码:
# Python with FastAPI
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
app = FastAPI()
FastAPIInstrumentor.instrument_app(app)
步骤 2:添加自定义属性
自动检测为你提供了骨架。自定义属性为你提供了血肉。为每个 span 添加业务上下文:用户 ID、租户 ID、功能标志、计划层级。这些是你在调试时需要查询的维度。
第 3 步:构建更少的仪表板
这听起来有悖直觉,但仪表板是可观测性消亡的地方。每个仪表板都是一个预设的问题。与其为每种可能的故障模式构建仪表板,不如投资于教导你的团队编写临时查询来查询你的 trace 和事件数据。工具应该是查询界面,而不是一堵图表墙。
第 4 步:通过游戏日进行练习
构建可观测性能力的最佳方式是注入故障,并仅使用你的可观测性工具来练习调试它们。你的团队能否使用当前工具在 15 分钟内找到延迟激增的根本原因?如果不能,你的可观测性技术栈需要改进。
成本问题
可观测性工具很昂贵,因为高基数数据的存储和查询成本很高。但替代方案——在事件中盲目飞行——代价更高。关键在于智能采样:保留 100% 的错误 trace、100% 的慢速 trace,以及其他所有内容的统计样本。这通常可以将数据量减少 80-90%,同时保留调试实际问题的能力。
你的仪表板并非故意欺骗你。它们回答的是你提出的问题。问题在于,生产系统的故障方式是你没有想到去询问的。你提出的问题和你需要提出的问题之间的差距,正是可观测性存在的地方。
