用途
该技能面向微服务与分布式系统中的链路追踪实践,适用于以下场景:为微服务引入分布式追踪、排查跨服务请求问题、理解 Trace 上下文传播、选择追踪基础设施、以及关联日志、指标与链路数据。
它以「请求流经多个服务时如何调试」为核心问题:没有追踪时,只能看到「用户 → API → ??? → 某处报错」;有了追踪后,可以看到「用户 → API(50ms) → OrderService(20ms) → PaymentService(ERROR: timeout)」,从而获得完整的请求流可见性。
核心概念
Trace、Span 与 Context
- Trace:端到端的请求旅程。
- Span:服务内的单次操作,包含 SpanID、ParentSpanID、TraceID、操作名、开始/结束时间(时长)、状态(成功/错误)、属性(键值元数据)与事件(时间点注解)。
- Context:跨服务边界传播,携带 TraceID、SpanID、Trace Flags 与 Trace State。
资料给出了 Trace 可视化示例:TraceID 为 abc123,API Gateway 总耗时 200ms,其下 Order Service 150ms,再下 Inventory 50ms、Payment 80ms,Payment 又调用外部 API 60ms。
OpenTelemetry
OpenTelemetry 被描述为统一的观测框架。组件包括 SDK、Tracer Provider、Meter Provider,通过 OTLP Exporter 发送,可经过(可选的)Collector,最终写入 Jaeger、Zipkin 或 Tempo 等后端。
Trace Context 传播
采用 W3C Trace Context HTTP 头:
traceparent: 00-{trace-id}-{span-id}-{flags}tracestate: vendor1=value1,vendor2=value2
示例:
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
│ │ │ └─ sampled
│ │ └─ parent span id
│ └─ trace id (128-bit)
└─ version
传播过程:Service A 创建 Span 并注入头部,通过 HTTP 传给 Service B;Service B 提取上下文并创建 Span。
Span 属性(语义约定)
- HTTP:http.method、http.url、http.status_code、http.route
- 数据库:db.system、db.statement、db.operation
- RPC:rpc.system、rpc.service、rpc.method
- 自定义:user.id、order.total、feature.flag
追踪后端
Jaeger
- 开源(CNCF)、内置 UI、支持多种存储后端、原生支持 OpenTelemetry。
- 架构:Agent(可选)→ Collector → Storage(Cassandra/Elasticsearch),Collector 同时写入 Query Service → UI。
Zipkin
- 成熟、久经考验、架构简单、资源开销低、生态支持好。
- 适合:较简单的部署、资源较少的环境、熟悉 Zipkin 的团队。
Grafana Tempo
- 对象存储后端(成本低)、与 Grafana 深度集成、基于日志的 Trace 发现、支持 Exemplars。
- 适合:以 Grafana 为主的环境、对成本敏感的部署、大规模 Trace。
云原生选项:AWS X-Ray(原生 AWS 服务)、GCP Cloud Trace(原生 GCP 服务)、Azure Application Insights(原生 Azure 服务)、Datadog APM(全栈可观测性)。
采样策略
高流量系统会产生海量 Span,全量存储昂贵且往往无必要,因此需要采样,目标是在控制成本的同时保留足够调试数据。
采样类型:
- 头部采样(Trace 开始时决策):跨服务一致,简单,但可能漏掉罕见事件。
- 尾部采样(Trace 完成后决策):可保留错误、慢请求等有价值的 Trace,但需要缓冲 Span,基础设施更复杂。
- 优先级采样:按属性赋优先级,保留全部错误、对正常流量采样。
采样策略:
- 基于速率:对所有 Trace 采样 10%,简单、成本可预测。
- 基于优先级:错误 100%、慢请求(>1s)100%、正常请求 5%。
- 自适应:根据流量调整速率,以每秒特定 Trace 数为目标,应对流量峰值。
关联模式
可观测性三大支柱为日志、链路与指标,通过以下方式关联:
- 在日志条目中加入 trace_id/span_id。
- 在指标中加入 Exemplars(指向 Trace 的链接)。
- 支持从指标 → Trace → 日志的跳转。
日志关联示例结构化日志:
{
"timestamp": "2024-01-15T10:30:00Z",
"level": "ERROR",
"message": "Payment failed",
"trace_id": "abc123def456",
"span_id": "789xyz",
"service": "payment-service",
"user_id": "12345",
"error": "Card declined"
}
在日志聚合中查询 trace_id:"abc123def456" 即可看到该请求的全部日志。
Exemplars(指标到 Trace):指标 http_request_duration{service="api"} = 2.5s 携带 exemplar: trace_id=abc123。延迟飙升时,可在仪表盘点击数据点直接跳到慢 Trace,查看延迟原因。
埋点模式
自动埋点(零代码):覆盖 HTTP 客户端/服务端、数据库客户端、消息队列、gRPC。优点是简单全面,缺点是控制力弱、噪声多。
手动埋点:为业务逻辑添加 Span,示例:
with tracer.start_span("process_order") as span:
span.set_attribute("order.id", order_id)
span.set_attribute("order.items", len(items))
result = process(order)
if result.error:
span.set_status(Status(StatusCode.ERROR))
span.record_exception(result.error)
优点是精确、与业务相关,缺点是代码更多、需要维护。
混合方案(推荐):1. 自动埋点基础设施(HTTP、数据库、队列调用);2. 手动埋点业务逻辑(关键操作、业务指标、错误上下文)。
最佳实践
Span 命名
- 好的名称:
HTTP GET /api/orders/{id}、ProcessPayment、db.query users。 - 差的名称:
Handler(过于笼统)、/api/orders/12345(基数爆炸)、doStuff(无意义)。
属性规范
- 应做:使用语义约定、加入业务上下文(user_id、order_id)、保持低基数、包含错误详情。
- 不应做:加入 PII(个人身份信息)、把高基数值作为属性、加入大载荷、包含敏感数据。
性能注意事项:1. 使用异步 Span 导出;2. 合理采样;3. 限制属性数量;4. 使用 Span 处理器批处理;5. 考虑 Span 数量上限。
用 Trace 排查问题
- 查找慢请求:按 duration > 阈值查询 Trace,识别慢 Span,检查属性获取上下文。
- 查找错误:按 status = ERROR 查询 Trace,查看错误 Span 与上下文,检查异常详情。
- 查找依赖:从 Trace 查看服务地图,识别关键路径,发现隐藏依赖。
相关技能
- observability-patterns:三大支柱概览
- slo-sli-error-budget:用 Trace 计算 SLI
- incident-response:在事故响应中使用 Trace
限制
资料未提供该技能的安装方式、依赖要求、支持的语言或框架清单、定价与收费信息,也未提供具体的代码库地址或示例仓库,这些内容暂未提供。