3. 追踪数据采集架构:Agent 采集、SDK 埋点、无侵入式采集(eBPF)的对比与选型
在分布式追踪体系中,数据采集是决定覆盖度、性能开销与运维复杂度的核心环节。平台工程团队需要根据业务场景、技术栈与治理成熟度,在 Agent 采集、SDK 埋点与无侵入式采集(eBPF)三种主流方案中做出合理选型。本章从架构原理、接入成本、数据质量与适用边界四个维度进行系统性对比。
3.1 三种采集架构的核心原理
核心认知:三种方案并非互斥关系,生产环境中常采用“SDK + Agent”或“Agent + eBPF”的混合模式,以平衡覆盖度与性能。
3.1.1 Agent 采集(旁路代理模式)
Agent 以独立进程或 Sidecar 形式部署在宿主机或 Pod 内,通过监听网络流量、读取日志文件或对接运行时接口来捕获追踪数据。典型实现包括 Jaeger Agent、OpenTelemetry Collector 与 SkyWalking Agent。
- 部署形态:DaemonSet(K8s)、Sidecar、主机级守护进程。
- 数据来源:网络 socket 嗅探、日志 tail、Unix Domain Socket 接收。
- 典型场景:已有 SDK 埋点但需要统一汇聚、协议转换或采样控制。
3.1.2 SDK 埋点(代码级侵入式)
SDK 以库的形式嵌入应用代码,通过 AOP(面向切面编程)、拦截器或手动插桩生成 Span。OpenTelemetry SDK、Jaeger Tracer、Zipkin Brave 均属此类。
- 部署形态:依赖注入、Maven/Gradle 包、npm 包。
- 数据来源:应用内部上下文(线程局部变量、异步钩子)。
- 典型场景:需要精确控制 Span 边界、携带业务标签、跨线程/跨异步追踪。
3.1.3 无侵入式采集(eBPF 内核态)
eBPF 在内核态挂载钩子,拦截系统调用、网络包、函数入口/出口,无需修改应用代码即可捕获 RPC 调用、数据库操作与文件 I/O 的时序数据。Cilium、Pixie、Apache SkyWalking eBPF 探针是代表项目。
- 部署形态:内核模块加载、特权容器、Operator。
- 数据来源:kprobe、tracepoint、uprobe、XDP。
- 典型场景:遗留系统、第三方闭源组件、全量网络拓扑发现。
选型警告:eBPF 无法捕获应用层自定义业务标签(如订单 ID、用户等级),且对内核版本有强依赖(推荐 5.10+)。SDK 埋点虽灵活,但多语言维护成本随微服务数量线性增长。
3.2 多维度对比矩阵
| 对比维度 | Agent 采集 | SDK 埋点 | eBPF 无侵入 |
|---|---|---|---|
| 代码侵入性 | 低(仅需配置) | 高(需修改代码) | 无(零修改) |
| 部署复杂度 | 中(需管理 Agent 生命周期) | 低(依赖管理即可) | 高(内核兼容性、特权要求) |
| 数据丰富度 | 中(依赖协议解析) | 高(可携带业务上下文) | 中(仅系统级元数据) |
| 性能开销 | 低~中(网络抓包有损耗) | 低(仅 Span 创建时) | 极低(内核态零拷贝) |
| 多语言支持 | 语言无关 | 需每种语言独立 SDK | 语言无关 |
| 异步/协程追踪 | 困难(上下文丢失) | 原生支持(Context 传播) | 困难(需 uprobe 辅助) |
| 运维依赖 | Agent 升级/配置管理 | SDK 版本对齐 | 内核版本、安全策略 |
3.3 采集架构选型决策树
平台工程团队在选型时,建议按以下优先级依次评估:
- 是否允许修改应用代码? 否 → 优先 eBPF(系统级)或 Agent(网络级);是 → 进入下一步。
- 是否需要业务级标签(如用户 ID、订单号)? 是 → 必须使用 SDK 埋点;否 → 考虑 Agent 或 eBPF。
- 技术栈是否统一(如全 Java/Go)? 是 → SDK 埋点性价比最高;否 → Agent 或 eBPF 更通用。
- 性能敏感度是否极高(P99 < 5ms)? 是 → eBPF 内核态采集开销最低;否 → SDK 或 Agent 均可。
- 是否有遗留系统或第三方组件? 是 → 混合方案:SDK 覆盖核心服务 + eBPF 覆盖黑盒组件。
平台工程最佳实践:在 K8s 环境中,推荐“OpenTelemetry SDK(业务服务)+ eBPF(网络代理/Service Mesh)+ Agent(统一 Collector)”的三层采集架构。SDK 负责业务上下文,eBPF 负责无侵入覆盖,Agent 负责协议转换与采样降级。
3.4 采集架构对比总览图
3.5 混合采集架构部署拓扑
下图展示了一个典型的生产级混合采集部署拓扑,适用于 K8s 环境下的微服务集群:
3.6 选型决策清单
| 场景特征 | 推荐方案 | 理由 |
|---|---|---|
| 全 Java 技术栈,团队可控 | SDK 埋点 | 最低开销、最丰富上下文、最易调试 |
| 多语言异构,无统一 SDK | Agent + eBPF | 语言无关,统一采集面 |
| 遗留系统无法修改代码 | eBPF 无侵入 | 零修改,快速覆盖 |
| 需要全量网络拓扑 | eBPF + Agent | eBPF 捕获网络流,Agent 做协议解析 |
| 核心交易链路需精细追踪 | SDK 埋点 + Agent | SDK 保证业务标签,Agent 保证汇聚质量 |
| 性能敏感(P99 < 3ms) | eBPF 为主 | 内核态零拷贝,无用户态上下文切换 |
平台工程关键指标:在混合采集架构中,需持续监控以下三个 SLO:
• 采集覆盖率 ≥ 95%(所有服务至少被一种方案覆盖)
• Span 丢失率 ≤ 1%(Agent 或 eBPF 采样导致的丢失)
• 额外延迟注入 ≤ 0.5ms(SDK 或 eBPF 对请求延迟的影响)
• 采集覆盖率 ≥ 95%(所有服务至少被一种方案覆盖)
• Span 丢失率 ≤ 1%(Agent 或 eBPF 采样导致的丢失)
• 额外延迟注入 ≤ 0.5ms(SDK 或 eBPF 对请求延迟的影响)
3.7 常见选型误区与避坑
- 误区一:eBPF 可以完全替代 SDK。 事实:eBPF 无法捕获应用层业务上下文,无法替代 SDK 在异步/协程场景下的 Context 传播。
- 误区二:Agent 采集是“零侵入”。 事实:Agent 虽不修改代码,但需管理 Agent 生命周期、配置与版本,运维成本不可忽视。
- 误区三:SDK 埋点性能开销可忽略。 事实:在高并发(>10k QPS)场景下,SDK 的 Span 创建与序列化仍会产生 1-3% 的 CPU 开销,需配合采样策略。
- 误区四:全量采集优于采样。 事实:全量采集在 1000+ 服务规模下会导致存储成本爆炸,必须设计动态采样策略(如 Head-Based + Tail-Based 混合采样)。
生产级建议:在引入 eBPF 前,务必验证目标集群的内核版本(uname -r)是否 ≥ 5.10,并确认安全策略允许加载 eBPF 程序。对于金融、合规敏感场景,eBPF 的内核态数据捕获可能需要额外的安全审计。