Files
cs-note/hzh/MS/04-可观测性/03-链路追踪.md
T
2026-05-24 11:42:38 +08:00

167 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [microservice, tracing, opentelemetry, context-propagation]
create time: 2026-05-05
---
# 链路追踪
## 概述
Tracing 回答的问题是:**请求在哪一步慢了 / 失败了?**——通过完整的调用链定位瓶颈和故障。
一次请求在多个服务中的完整调用路径:
```mermaid
flowchart LR
RID["Request<br/>trace_id: abc-123"]
subgraph SPANS["调用链 (Trace)"]
direction TB
S1["Span #1<br/>API Gateway<br/>5ms"]
S2["Span #2<br/>Order Service<br/>70ms"]
S3["Span #3<br/>Payment RPC<br/>160ms"]
S4["Span #4<br/>Inventory RPC<br/>70ms"]
S1 --> S2 --> S3
S2 --> S4
end
RID --> S1
style S3 fill:#ff9999
note["Span #3 耗时最长 → Payment 是瓶颈"]
S3 -.-> note
```
## Trace/Span 核心概念
| 概念 | 说明 |
|------|------|
| **Trace** | 一次请求的完整调用链,全局唯一 `trace_id` |
| **Span** | 调用链中的一个执行单元,有独立的 `span_id` |
| **Parent-Child** | Span 树状结构,子 Span 继承父 Span 的 trace_id |
| **Tags / Attributes** | 键值对标注(HTTP method、status code) |
| **Logs** | Span 级别的时间戳事件(如 "DB query started") |
| **Sampling** | 按比例采样,降低存储开销 |
### OpenTelemetry W3C Trace Context 标准
```json
// HTTP Header
{
"traceparent": "00-{trace_id}-{span_id}-01",
"tracestate": "vendor=value"
}
```
格式解析:`version(2字节) - trace_id(32字节) - span_id(16字节) - flags(2字节)`
```
示例: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ └─── trace_id ───┘ └─ span_id ─┘ └flags─┘
```
## 上下文传播详解
`trace_id` 必须从上游传递到下游。不同通信场景有不同的传播方式:
### HTTP 传播
```go
func Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 1. 提取入站 trace context
ctx := propagator.Extract(r.Context(), headerReader{r.Header})
// 2. 创建新的 Span
ctx, span := tracer.Start(ctx, "handleRequest")
defer span.End()
// 3. 将 trace context 注入出站请求
r = r.WithContext(ctx)
propagator.Inject(ctx, headerWriter{r.Header})
next.ServeHTTP(w, r)
})
}
```
### MQ 消息头传播
```go
// 生产者 - 手动注入 trace context
msg.Properties.Set("trace_id", extractTraceID(ctx))
msg.Properties.Set("span_id", extractSpanID(ctx))
// 消费者 - 恢复 trace context
traceID := msg.Properties.Get("trace_id")
span, _ := tracer.Start(traceContext, "consumeMessage",
trace.WithAttributes(attribute.String("mq.message.id", traceID)))
```
## 采样策略
```mermaid
flowchart TD
AllReq["全部请求"] --> Sampler{"采样决策"}
Sampler -->|"100%"| Core["核心链路全量采集"]
Sampler -->|"5~10%"| Normal["普通路径随机采样"]
Sampler -->|"100%"| Error["错误链路优先保留"]
Sampler -->|"0%"| Health["健康检查/内部心跳"]
Core --> Storage["Trace 存储"]
Normal --> Storage
Error --> Storage
Health --> Drop["丢弃"]
```
| 环境 | 采样率 | 说明 |
|------|--------|------|
| 开发 / 测试 | 100% | 方便调试,无存储压力 |
| 生产 - 核心链路 | 100% | 下单、支付等关键路径 |
| 生产 - 普通路径 | 5~10% | 平衡成本和覆盖率 |
| 生产 - 错误链路 | 100% | 出错时优先保留 |
> [!tip] 基于错误的智能采样
>
> 高级做法:**正常路径低采样,一旦检测到 HTTP 5xx 或 DB 超时,立即提升当前请求的采样率**。这样既省了存储,又能在出问题时有足够的数据回溯。
## 主流方案对比
| 方案 | 存储后端 | 侵入程度 | 中文支持 | 推荐理由 |
|------|---------|---------|---------|---------|
| **OpenTelemetry** | 任意 Jaeger/Prometheus/Loki | SDK + Auto-instrumentation | 良好 | CNCF 行业标准,未来趋势 |
| **Jaeger** | Cassandra / Elasticsearch | Agent / SDK | 社区支持 | Uber 开源,UI 优秀 |
| **SkyWalking** | MySQL / ES | 零侵入 Agent | ⭐ 完善 | 国产首选,开箱即用 |
## 渐进式落地路线
> [!tip] 不要试图一步到位——先从 Tracing 开始,ROI 最高。
>
> 1. **第一步**:接入 Tracing(OpenTelemetry),覆盖核心链路(下单、支付),rate=100%
> 2. **第二步**:加 Metrics(Prometheus + Grafana),建立基础监控面板
> 3. **第三步**:集中 Logging(Loki / ELK),日志携带 trace_id 与 Tracing 关联
> 4. **第四步**:全量上 OpenTelemetry Collector,统一管理三件套
## 性能影响评估
| 指标 | 预期影响 |
|------|---------|
| CPU 增加 | < 3%(异步批量上报) |
| 内存增加 | ~10MB(Span buffer) |
| 网络带宽 | 每条 Trace 约 2~5KB(取决于 Span 数量) |
| 延迟增加 | < 0.1ms(SDK 内处理不阻塞业务) |
> [!note] 关键实践
> - 使用 **BatchProcessor** 异步上报,不阻塞业务线程
> - Span 不要嵌套过深,一个 HTTP 调用或 DB 查询对应一个 Span
> - 给 Span 设置丰富的 Attributes,方便查询和过滤
> - 错误 Span 标记 `isError=true`,便于快速定位问题链路
## 关联笔记
- [[04-可观测性/01-Metrics监控]] — Tracing 与 Metrics 互补
- [[04-可观测性/02-日志系统]] — trace_id 串联日志和追踪
- [[04-可观测性/04-告警管理]] — 基于 Trace 数据的异常检测告警