微服务化之后,一次请求跨十几个服务,日志散落、指标孤立,定位慢接口要翻半天。本文给出以链路追踪为轴心、日志与指标协同的排查方案,包含采样策略、错误指纹聚合与告警联动,帮助团队把 MTTR 从小时级压到分钟级。
微服务化带来的典型困境:用户报「下单卡了」,你看到网关 P99 飙高,但背后十几个服务里到底哪个慢,全靠人肉翻日志。日志是散的,指标是孤立的,链路才是把一次请求串起来的骨架。
炬鲸 OBSERVE 的方案以 Trace 为轴心:用链路定位「慢在哪一跳」,再用该跳的日志看「为什么慢」,最后用指标看「影响多大」。三者围绕同一个 traceId 打通。
全量采样成本高,但固定 1% 采样又会漏掉偶发故障。我们推荐头部采样 + 尾部采样组合:
status = error 或 elapsed > 阈值,就强制保留整条链路。这样错误链路 100% 留存,正常链路低成本抽样。配置上,采集器把 trace 数据发给 OTLP 网关,网关做尾部判定:
sampling:
head:
probability: 0.10
tail:
force_keep:
- condition: "span.status == 'ERROR'"
- condition: "span.duration_ms > 1500"
定位到慢 Span 后,下一步是看它的日志。关键动作:
traceId + spanId 反查该 Span 生命周期内的所有日志行,不用再去日志界面手输条件。链路只回答「这次请求怎么样」,告警要回答「这影响面有多大」。把 trace 指标(延迟分位数、错误率)按服务维度导出到指标系统,告警规则直接消费:
alert: service_latency_p95_high
expr: trace_p95_ms{service="order"} > 1000
for: 5m
labels: {severity: warning}
annotations:
summary: "order 服务 P95 延迟超过 1s"
trace_query: "service=order AND elapsed>1000 ORDER BY elapsed DESC"
告警详情里直接带上 trace 查询链接,值班同学点开就是慢链路 Top 列表,省掉「从告警到证据」的拼装时间。
以 Trace 为中心,把日志和指标挂到链路上,故障定位从「翻几十个服务的日志」变成「点开一条慢链路、下钻一次日志」,MTTR 的压缩是实打实的。