面试考察点

  • 是否从 SLO 和用户影响出发,而不是只列工具。
  • 能否说明指标、日志、追踪和事件的互补关系。
  • 是否控制标签基数、采样、成本和敏感数据。

核心答案

指标用于快速发现趋势和告警,结构化日志提供离散事件细节,分布式追踪还原一次请求的跨服务路径,业务事件解释技术指标背后的用户影响。设计应从 SLI/SLO、关键用户旅程和故障假设出发,确保告警能指向可执行的排查入口。

常用入口指标可围绕请求量、错误、延迟和资源饱和度,并按服务依赖继续下钻。

上下文关联

请求在边界生成或接收 trace id,在服务、消息和异步任务间传播;日志记录 trace id、业务操作 id 和稳定错误码。消息链路还要保留原 trace 关系或 link,避免异步后完全断链。

从 SLO 反推信号

先定义“用户是否成功”:例如支付请求成功率、搜索 P99、消息端到端延迟、配置生效时间。再建立对应 SLI:请求量、错误、延迟、饱和度、Lag、版本差异等。仅采集 CPU、内存和 JVM GC 不能说明用户是否受影响;同样,接口 200 也可能返回业务失败。

用户旅程 SLO -> 服务 SLI -> 依赖指标 -> 日志/trace 证据 -> 可执行告警

告警应表达“预算正在消耗且需要动作”,例如过去 10 分钟 P99 超过阈值并影响 5% 请求,而不是每个 Pod CPU 短暂升高都通知值班人员。

指标设计与高基数

指标标签适合有限集合:service、route template、status class、region、instance;不要把 user_id、order_id、完整 URL、异常堆栈放成 Prometheus label,这会造成时间序列爆炸。高基数字段进入结构化日志或 trace span,按需检索。

请求指标至少区分成功/业务拒绝/系统错误、路由模板和依赖;队列类系统同时记录入口速率、处理速率、当前积压和最老消息年龄。资源指标要和容量上限关联,而不是只画当前值。

结构化日志规范

{
  "timestamp":"2026-07-22T10:00:00Z",
  "level":"WARN",
  "service":"order-api",
  "trace_id":"t-01",
  "operation_id":"op-1001",
  "error_code":"INVENTORY_TIMEOUT",
  "duration_ms":312,
  "retry_count":1
}

日志应可机器解析,字段命名稳定,敏感信息脱敏,避免把 token、身份证、支付数据和完整请求体写入。错误码比自然语言更适合聚合;堆栈应在最有上下文的边界记录一次。

Trace 的采样策略

全量 trace 对高吞吐服务成本很高,可保留错误、慢请求、关键交易和随机代表样本。采样决定要在入口保持一致,否则一条请求在下游突然丢失。异步消息使用 parent/links 传播,批量处理要注意一个 span 包含多少消息,避免产生海量子 span。

告警与成本

告警优先基于用户可感知 SLO 消耗和持续异常,减少瞬时噪声。高基数字段不能直接做指标标签,明细进入日志或追踪;采样要保留错误、慢请求和关键业务,并设置数据保留层级。

常见误区

日志越多不等于可观测性越好,无结构、无上下文和重复堆栈只增加成本。平均延迟会掩盖长尾,应关注分位数、错误预算和分组后的异常差异。

告警到排障闭环

告警 -> 确认用户影响/变更时间 -> 看入口 P99/错误预算
     -> trace 找慢依赖 -> 日志核对错误码与参数
     -> 指标验证容量/资源 -> 止损/修复 -> 验证 SLO 恢复

告警页面应提供 dashboard、最近发布、关联 trace 查询和 runbook 链接。故障结束后记录检测时间、定位时间、恢复时间、误报和缺失信号,推动新增监控而非只扩大日志量。

成本和保留

按数据价值分层保留:指标保留长周期用于趋势,错误和慢 trace 保留更久,普通 debug 日志短期采样;冷热存储、压缩和脱敏都要纳入预算。可观测性系统本身也需要限流,避免故障风暴把日志平台打崩。

高频追问与参考回答

追问:线上故障如何从告警开始定位?

先确认用户范围和变更时间线,再按入口指标定位服务与依赖,通过 trace 找慢点或错误点,用结构化日志验证具体失败,最后用业务指标确认恢复。

追问:为什么不把所有请求都采全量 Trace?

成本、存储、网络和查询压力可能随流量线性增长。应优先保留错误、慢请求、关键交易和代表样本,并保证跨服务采样策略一致。

追问:日志里应该记录完整请求体吗?

通常不应。敏感信息、超大 payload 和个人数据会带来安全与成本风险;应记录稳定操作 ID、摘要、错误码和必要字段,调试数据使用受控采样。

追问:业务指标和技术指标冲突怎么办?

先确认口径和时间窗口。例如接口 200 但支付成功率下降,说明技术健康指标没有覆盖业务结果;应把业务事件和技术 trace 关联起来定位。

追问:指标告警为什么会疲劳?

阈值过多、没有用户影响、没有去重和恢复条件都会产生噪声。以 SLO/错误预算为核心,按持续时间和影响范围触发可执行告警。

总结

可观测性不是数据采集项目,而是“发现、定位、解释、恢复验证”的工程闭环,并受成本和隐私约束。

机制全景图

下面把「分布式系统的可观测性应该如何设计?」从输入到结果压缩成一条可复述的主链路。面试时先用图建立全局坐标,再进入局部实现,能避免只背零散结论。

flowchart LR
    A["请求进入生成 Trace/Request ID"]
    A --> B["各服务记录结构化日志"]
    B --> C["采集指标与分布式 Span"]
    C --> D["关联发布和业务事件"]
    D --> E["告警定位并驱动处置"]

完整链路:从输入到结果

沿着「请求进入生成 Trace/Request ID → 各服务记录结构化日志 → 采集指标与分布式 Span → 关联发布和业务事件 → 告警定位并驱动处置」观察输入、状态与输出,下面每个阶段都对应一个可以在源码、日志或系统表中验证的位置。

1. 请求进入生成 Trace/Request ID

入口生成或接受可信请求标识,并在日志、消息和下游调用中传播,避免链路断点。

2. 各服务记录结构化日志

日志记录离散事件和上下文,必须结构化、分级并控制敏感字段与高基数。

3. 采集指标与分布式 Span

指标适合趋势和告警,Trace 展示单请求因果与耗时;三者不能互相完全替代。

4. 关联发布和业务事件

发布、配置、扩容和业务活动作为事件叠加到时间轴,能快速判断相关性。

5. 告警定位并驱动处置

告警应从 SLO 与用户影响出发,包含负责人、Runbook 和可执行上下文,避免只报 CPU 高。

源码与实现定位

入口 阅读重点
OpenTelemetry semantic conventions Trace/Metric 属性
SLO burn-rate rule 用户影响告警

源码或系统表应按上表顺序追踪:先确认入口实际走到哪条路径,再用运行时数据验证,而不是仅凭类名或配置推测。

参数配置与可复现实验

http.server.request.duration{service,route,status}
trace_id/request_id/tenant_id/release_version

注入单租户错误、慢依赖和发布回归,验证能从告警到 Trace 再到日志。

验证步骤与预期结果

1. 固定输入和基线

先在没有故障注入的环境执行上述配置,固定数据规模、并发度、运行时版本和预热时间。以「错误 Trace 完整率」为主基线,记录值应满足「记录活动/稳态基线」;同时保存 RED/USE 指标、SLO burn rate,使后续变化能够回到同一时间轴比较。

2. 从实现入口确认路径

在「OpenTelemetry semantic conventions」确认请求确实进入「Trace/Metric 属性」对应的实现,再沿「SLO burn-rate rule」观察「用户影响告警」。如果入口路径都未命中,就不应继续调整下游参数,而应先检查调用条件、版本或路由是否与假设一致。

3. 注入本文特有的失败模式

优先复现「日志高基数字段导致成本失控」,并把单一变量逐级放大,直到「错误 Trace 完整率」越过「超过容量或 SLO」。随后再分别验证「只监控资源不监控业务成功率」和「Trace 采样漏掉稀有错误且无错误保留策略」,三类故障分开执行,避免多个变量同时变化而无法归因。

4. 执行止损和根因修复

第一轮只应用「错误与长尾优先采样」,确认它能控制影响范围;第二轮应用「限制高基数标签」,验证核心链路恢复;最后落实「告警带 owner/runbook/release」,消除同类问题再次出现的条件。每一步都保留变更前后数据,不用“感觉变快了”替代测量。

5. 通过退出条件

实验只有同时满足三项才算通过:「错误 Trace 完整率」回到「记录活动/稳态基线」、「端到端 P99」回到「小于预算」、「状态差异」回到「0」,并且业务结果差异为零。若性能恢复但结果不一致,仍应视为失败;若指标恢复后很快再次越线,则说明只完成了临时止损,没有消除根因。

量化基线

指标 样例基线/口径 风险线 结论
错误 Trace 完整率 记录活动/稳态基线 超过容量或 SLO 触发降级
端到端 P99 小于预算 突破预算 停止扩量
状态差异 0 任意非零 补偿并对账

这些数值是实验口径或示例告警线,不是可复制到所有系统的固定答案;上线阈值应由本系统稳态、峰值和故障演练共同确定。

事故复盘:接口错误率升高却无法定位租户

日志只有异常堆栈,没有 tenant_id、request_id 和发布版本;指标又只按全局聚合。补齐统一上下文、按受控维度拆分 RED 指标并串联 Trace 后,发现单租户异常输入触发。

失败模式 首要证据 第一处置动作
日志高基数字段导致成本失控 RED/USE 指标 错误与长尾优先采样
只监控资源不监控业务成功率 SLO burn rate 限制高基数标签
Trace 采样漏掉稀有错误且无错误保留策略 Trace 完整率 告警带 owner/runbook/release

发布与回滚检查点

  • 发布前:确认「OpenTelemetry semantic conventions」对应实现和上述配置在目标版本仍然有效,并保存「错误 Trace 完整率」基线。
  • 灰度中:同时观察 RED/USE 指标、SLO burn rate、Trace 完整率;任一指标越过表中风险线,就停止继续扩量。
  • 回滚时:先执行「错误与长尾优先采样」控制影响,再回退代码或参数;涉及持久状态时必须额外核对结果差异。
  • 发布后:至少覆盖一个完整峰值周期,确认「日志高基数字段导致成本失控」没有再次出现,才关闭变更观察窗口。

方案对比与选型

方案 更适合的场景 主要收益 代价与边界
日志 离散错误与详细上下文 证据丰富、可审计 成本高且全文检索慢
指标 趋势、聚合和告警 存储高效、适合 SLO 高基数受限,细节少
Trace 跨服务因果与单请求长尾 定位链路瓶颈 采样、上下文传播与成本

选型至少带上 峰值流量、数据规模、依赖容量、一致性目标和故障预算,并用上面的量化基线验证;未知数据应明确为待测假设。

设计边界与工程取舍

可观测性不是“收集更多数据”,而是让系统内部状态能被外部证据解释;每个信号都应服务一个诊断或决策问题。

工程落地遵循:先定义 SLO 与不变量,再通过限流、隔离、异步和补偿保护核心链路。回答时直接引用「OpenTelemetry semantic conventions」、配置实验和事故数据,比复述固定模板更有说服力。