收到“订单查询失败增加”的告警之后,值班人员通常要完成几个动作:确认哪些用户受影响,找到一条失败请求,判断时间花在应用还是依赖上,执行止损,再观察用户能力是否恢复。
可观测性的最小实现围绕这条排查过程组织。小系统不必堆叠工具,但指标、日志和追踪必须共享服务标识、版本与请求上下文,否则值班人员无法从一个信号跳到另一个信号。
指标先回答影响范围
请求数、失败数、耗时分布和在途量能提供一组基础信号。状态码不足以表达全部业务失败,业务还应定义“什么算成功完成”。限流、降级和正常业务拒绝可以单独记录,避免混在同一个错误率里。
标签尽量选择有限集合,例如服务名、环境、路由模板和错误类别。订单 ID、用户 ID、完整 URL 和查询文本会使时序数量随业务增长,不适合直接放进普通指标标签。需要定位单个请求时,再到受访问控制的日志或追踪中查找。
路由也要用 /orders/:id 这样的模板,不要记录每个具体 ID。基数问题并非只有存储费用,它还会拖慢查询,让告警计算在故障时变得不可靠。
下面是假设应用暴露 Prometheus classic histogram 的示例,单位为秒:
histogram_quantile(
0.95,
sum by (service, le) (
rate(http_request_duration_seconds_bucket{
environment="production",
route="/orders/:id"
}[5m])
)
)
http_request_duration_seconds_bucket 及其标签是示例指标约定,不是承诺某个 OpenTelemetry SDK 默认就导出这些名字。接入时需要核对实际映射。
这里先计算桶增量速率,再聚合同一服务的实例,最后估算 P95。各实例应使用兼容的桶边界。把不同实例的 P95 平均起来,无法得到整体 P95;相关区别见 Prometheus 的直方图与摘要说明。
桶边界也影响精度。若服务目标在某个延迟附近,桶设置应能分辨目标附近的变化。五分钟窗口只是示例;低流量时,一个百分位可能缺乏稳定样本,必须结合请求量解释。没有数据也不能显示成零延迟或零错误。
用日志保存诊断所需的事实
指标告诉人哪里发生变化,日志应提供一条事件的细节。可以从请求结束事件开始,固定字段和单位,避免每条记录都拼一段无法检索的自然语言。
以下日志完全虚构,仅展示字段关系:
{
"event": "request_completed",
"service": "order-query",
"environment": "production",
"release": "example-v1",
"route": "/orders/:id",
"status_code": 503,
"duration_ms": 812,
"error_kind": "dependency_timeout",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"span_id": "00f067aa0ba902b7"
}
duration_ms 与前面直方图的秒不同,因此字段名保留单位。真实记录还需要可靠的时间戳。相同事件在不同服务里应尽量使用一致的错误分类,避免告警按一个名字统计、日志却记录另一个名字。
不要默认记录请求正文、认证头、Cookie 或完整 SQL 参数。必要的业务标识也应有明确用途、访问权限和保留期。脱敏应该在采集前完成,不能等数据进入多个后端后再补救。
追踪补上调用关系
一个服务生成请求 ID,另一个服务再独立生成请求 ID,两份日志不会因此自动形成调用链。跨服务追踪需要传播上下文,让下游 span 与上游 span 建立父子或其他因果关系。
OpenTelemetry 用上下文传播关联分布式调用,并允许日志携带 trace ID 和 span ID。具体机制见 上下文传播文档与日志规范。应用应核对所用语言 SDK、HTTP 客户端和消息客户端是否实际完成了注入与提取,不能只看库是否安装。
收到外部 trace header 时,也不能把它当作可信身份。格式验证、边界策略和采样限制仍然必要。内部凭据与个人信息不应放入会沿调用链传播的 baggage。
一个请求慢,可能来自数据库执行,也可能在取得连接之前排队。如果只给 SQL 执行建立 span,追踪中会出现无法解释的空白。应按排查需要覆盖连接等待、关键远程调用和主要业务阶段,而不是为每个小函数都创建 span。
异步消息也要保留生产与消费的关联。两次执行可能并不处在同一条同步请求树里,使用父子关系还是 link,应按消息语义和 SDK 能力决定。
采样会留下缺口,排查流程要承认它
头部采样在请求开始时决定是否保留追踪,开销易控制,但通常还不知道请求最后是否出错。尾部采样可以利用最终结果做选择,不过需要缓存待决 trace,并保证采集流程能获得足够完整的数据。
无论采用哪种方式,界面都应该允许“这条日志没有对应 trace”。不能因为采样后没有看到错误追踪,就认为服务没有失败。用于 SLO 的请求指标通常应独立于 trace 采样统计,具体接入链路需确认。
告警链接应带上服务、时间范围、版本等定位条件。若系统支持从直方图样本跳转 trace,可以增加入口;不支持时,也可以先查同时间范围的结构化错误日志。一个能用的查询路径比一张信息很多却无法跳转的仪表盘更重要。
闭环要走到恢复确认
最小告警说明应包含用户能力、责任人、可考虑的止损动作和判断恢复的方法。例如依赖超时告警可以链接到降级开关说明,但权限服务故障不能复用“放行请求”的降级动作。
执行止损后,继续观察成功完成量、失败与拒绝量、积压和依赖恢复情况。只看到告警消失还不够:采集器故障、指标停止上报或流量被全部挡住,也会让某些错误曲线下降。
采集系统自身也要监控丢弃量、导出失败和队列积压。导出器应有有界缓冲,避免观测后端不可用时耗尽业务进程内存。保留策略则按信号用途制定,不必让高频调试日志与审计记录保存同样久。
用一次受控的依赖超时演练这条链路。值班人员应收到告警、找到失败样本、执行授权动作,再用用户指标确认恢复。记录缺失环节,流程文字本身不构成验证证据。
