4. 追踪数据采集:自动埋点与手动埋点策略、Agent 与 SDK 部署模式、采样策略
分布式追踪的数据采集是整个可观测性体系的“第一公里”。采集策略的优劣直接决定了故障排查时能否拿到有效数据,以及存储成本是否可控。本章从埋点方式、部署模式、采样策略三个维度展开,帮助值班台工程师在实战中做出合理选择。
4.1 自动埋点与手动埋点策略
埋点(Instrumentation)是将追踪代码注入应用程序的过程。根据注入方式的不同,分为自动埋点和手动埋点两大类。
| 对比维度 | 自动埋点 | 手动埋点 |
|---|---|---|
| 实现方式 | 通过字节码增强、AOP、中间件钩子自动注入 | 开发者在代码中显式调用 SDK API |
| 侵入性 | 零代码侵入,无需修改业务代码 | 高侵入,需要修改源码并重新编译 |
| 覆盖范围 | HTTP、gRPC、数据库、消息队列等通用组件 | 业务自定义逻辑、关键路径、事务边界 |
| 上下文丰富度 | 基础链路信息(耗时、状态码、请求大小) | 可携带业务标签、用户ID、订单号等语义信息 |
| 部署成本 | 低,通常通过 Agent 或启动参数一键接入 | 高,需要开发团队投入持续维护 |
| 典型场景 | 快速接入、存量系统、第三方组件 | 核心交易链路、自定义异步流程、错误诊断 |
值班台建议:推荐采用“自动埋点为主 + 手动埋点补充”的混合策略。自动埋点保证基础链路全覆盖,手动埋点用于关键业务路径和故障高发区域,避免过度埋点导致性能开销失控。
4.2 Agent 与 SDK 部署模式
部署模式决定了追踪能力如何交付到目标服务中。主流方案分为 Agent 模式和 SDK 模式,两者在运维复杂度、资源隔离、版本管理上存在显著差异。
4.2.1 Agent 模式
- 原理:以独立进程或 sidecar 形式部署,通过字节码增强或网络代理劫持应用流量。
- 优势:应用无感知,升级 Agent 无需重启业务进程;支持多语言统一管理。
- 劣势:额外资源开销(CPU/内存);对 Agent 稳定性要求高,故障可能影响宿主。
- 典型实现:Java Agent(如 OpenTelemetry Java Agent)、eBPF 内核级 Agent。
4.2.2 SDK 模式
- 原理:将追踪库以依赖形式引入应用代码,编译时链接。
- 优势:资源开销可控,与应用进程共享生命周期;可精细控制埋点行为。
- 劣势:升级 SDK 需要重新编译部署;多语言版本管理复杂。
- 典型实现:OpenTelemetry SDK、Jaeger Client、Zipkin Brave。
| 对比维度 | Agent 模式 | SDK 模式 |
|---|---|---|
| 部署方式 | 独立进程 / sidecar / 内核模块 | 代码依赖 / 编译时引入 |
| 升级影响 | 热升级,无需重启应用 | 需重新编译部署 |
| 资源隔离 | 独立进程,可单独限流 | 与应用共享资源 |
| 语言支持 | 通常绑定特定语言或内核 | 多语言 SDK 独立维护 |
| 故障影响面 | Agent 崩溃可能影响应用 | SDK 异常仅影响当前进程 |
| 适用场景 | 大规模集群、存量系统、快速接入 | 核心链路、精细控制、资源敏感 |
值班台避坑:Agent 模式虽然运维友好,但在高并发场景下需关注 Agent 自身的 CPU 和内存开销。建议为 Agent 设置独立的资源限制(如 cgroup),并配置熔断机制——当 Agent 处理延迟超过阈值时自动降级,避免 Agent 故障拖垮业务进程。
4.3 采样策略
在高吞吐分布式系统中,全量采集所有 Span 会产生海量数据,导致存储成本爆炸和查询性能下降。采样策略是平衡数据完整性与成本的关键手段。
4.3.1 头采样(Head Sampling)
在请求入口处(Trace 起始端)决定是否采样。一旦决定,整个 Trace 的所有 Span 要么全部采集,要么全部丢弃。
- 优点:实现简单,决策点单一,适合固定采样率场景。
- 缺点:无法根据请求执行过程中的特征(如错误、延迟)动态调整;低概率采样时容易丢失异常链路。
- 典型实现:固定概率采样(如 1%)、速率限制采样(每秒 N 条 Trace)。
4.3.2 尾采样(Tail Sampling)
先采集所有 Span 到本地缓冲区,待 Trace 结束后根据完整特征(是否包含错误、延迟是否超阈值、特定标签)决定是否保留。
- 优点:可基于完整 Trace 信息做决策,确保异常链路 100% 保留;支持复杂策略(如错误优先、慢调用优先)。
- 缺点:需要额外缓冲区存储,增加延迟和资源开销;实现复杂度高。
- 典型实现:OpenTelemetry Collector 的 tail_sampling 处理器、Jaeger 的尾部采样策略。
4.3.3 概率采样(Probabilistic Sampling)
基于 Trace ID 的哈希值或随机数,按固定概率决定是否采样。可独立应用于每个 Span,也可用于 Trace 级别。
- 优点:计算开销极低,适合超大规模集群;无状态,易于水平扩展。
- 缺点:无法感知请求内容,可能丢失关键异常链路。
- 典型实现:Trace ID 取模、随机数比较。
| 对比维度 | 头采样 | 尾采样 | 概率采样 |
|---|---|---|---|
| 决策时机 | Trace 起始 | Trace 结束 | Span 生成时 |
| 决策依据 | 固定规则 / 速率 | 完整 Trace 特征 | 随机 / 哈希 |
| 异常链路保留 | 低概率下易丢失 | 可 100% 保留 | 随机丢失 |
| 资源开销 | 低 | 高(需缓冲区) | 极低 |
| 实现复杂度 | 低 | 高 | 极低 |
| 适用场景 | 稳定流量、成本敏感 | 核心链路、故障诊断 | 大规模、无状态 |
值班台最佳实践:推荐采用“分层采样”策略——核心交易链路使用尾采样(100% 保留错误和慢 Trace),非核心链路使用概率采样(1%~5%),边缘服务使用头采样(固定 0.1%)。同时设置全局速率上限,防止突发流量冲垮后端存储。
4.4 采样策略组合与值班台实战
单一采样策略无法满足所有场景。值班台工程师需要根据业务重要性和故障排查需求,设计多级采样组合策略。
推荐组合策略(生产环境已验证):
- 核心交易链路(支付、下单、登录):尾采样 + 错误/慢 Trace 100% 保留 + 正常 Trace 10% 概率采样。
- 重要业务链路(搜索、推荐、消息):头采样 + 固定 5% 概率 + 速率限制 1000 Trace/s。
- 边缘服务(日志、监控、配置):概率采样 + 0.1% 固定概率。
- 全局兜底:所有服务配置最大速率上限(如 5000 Span/s),防止突发流量打爆 Collector。
# OpenTelemetry Collector 尾采样配置示例
processors:
tail_sampling:
decision_wait: 30s # 等待 Trace 结束的最长时间
num_traces: 100000 # 缓冲区最大 Trace 数
expected_new_traces_per_sec: 1000
policies:
- name: error-policy
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow-policy
type: latency
latency: { threshold_ms: 5000 }
- name: probabilistic-policy
type: probabilistic
probabilistic: { sampling_percentage: 10 }
值班台检查清单:
- 确认采样策略是否覆盖了所有核心故障场景(错误、超时、高延迟)。
- 检查采样率是否与存储容量匹配(建议预留 30% 存储余量)。
- 验证采样决策是否在 Collector 层面生效,避免 Agent 端重复采样。
- 定期审计采样数据,确保异常链路未被遗漏。